home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / shk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  83.1 KB  |  3,249 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)shk.c    3.1    93/05/19    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "eshk.h"
  7.  
  8. /*#define DEBUG*/
  9.  
  10. #define PAY_SOME    2
  11. #define PAY_BUY     1
  12. #define PAY_CANT    0    /* too poor */
  13. #define PAY_SKIP  (-1)
  14. #define PAY_BROKE (-2)
  15.  
  16. #ifdef KOPS
  17. STATIC_DCL void FDECL(makekops, (coord *));
  18. STATIC_DCL void FDECL(call_kops, (struct monst *,BOOLEAN_P));
  19. # ifdef OVLB
  20. static void FDECL(kops_gone, (BOOLEAN_P));
  21. # endif /* OVLB */
  22. #endif /* KOPS */
  23.  
  24. #define IS_SHOP(x)    (rooms[x].rtype >= SHOPBASE)
  25.  
  26. extern const struct shclass shtypes[];    /* defined in shknam.c */
  27.  
  28. STATIC_VAR NEARDATA long int followmsg;    /* last time of follow message */
  29.  
  30. STATIC_DCL void FDECL(setpaid, (struct monst *));
  31. STATIC_DCL long FDECL(addupbill, (struct monst *));
  32. STATIC_DCL void FDECL(pacify_shk, (struct monst *));
  33.  
  34. #ifdef OVLB
  35.  
  36. static void FDECL(clear_unpaid,(struct obj *));
  37. static struct bill_x *FDECL(onbill, (struct obj *, struct monst *, BOOLEAN_P));
  38. static long FDECL(check_credit, (long, struct monst *));
  39. static void FDECL(pay, (long, struct monst *));
  40. static long FDECL(get_cost, (struct obj *, struct monst *));
  41. static long FDECL(set_cost, (struct obj *, struct monst *));
  42. static const char *FDECL(shk_embellish, (struct obj *, long));
  43. static long FDECL(cost_per_charge, (struct obj *));
  44. static long FDECL(cheapest_item, (struct monst *));
  45. static int FDECL(dopayobj, (struct monst *, struct bill_x *,
  46.                 struct obj **, int, BOOLEAN_P));
  47. static long FDECL(stolen_container, (struct obj *, struct monst *, long,
  48.                      BOOLEAN_P));
  49. static long FDECL(getprice, (struct obj *));
  50. static struct obj *FDECL(bp_to_obj, (struct bill_x *));
  51. static boolean FDECL(inherits, (struct monst *, int, BOOLEAN_P));
  52. static struct monst *FDECL(next_shkp, (struct monst *, BOOLEAN_P));
  53. static boolean NDECL(angry_shk_exists);
  54. static void FDECL(rile_shk, (struct monst *));
  55. static void FDECL(remove_damage, (struct monst *, BOOLEAN_P));
  56. static void FDECL(sub_one_frombill, (struct obj *, struct monst *));
  57. static void FDECL(add_one_tobill, (struct obj *, BOOLEAN_P));
  58. static void FDECL(dropped_container, (struct obj *, struct monst *,
  59.                       BOOLEAN_P));
  60. static void FDECL(bill_box_content, (struct obj *, BOOLEAN_P, BOOLEAN_P,
  61.                      struct monst *));
  62. static void FDECL(shk_names_obj, (struct obj *));
  63.  
  64. /*
  65.     invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
  66.         obj->quan <= bp->bquan
  67.  */
  68.  
  69. static struct monst *
  70. next_shkp(shkp, withbill)
  71. register struct monst *shkp;
  72. register boolean withbill;
  73. {
  74.     for (; shkp; shkp = shkp->nmon)
  75.         if (shkp->isshk)
  76.         if (ESHK(shkp)->billct || !withbill) break;
  77.  
  78.     if (shkp) {
  79.         if (NOTANGRY(shkp)) {
  80.         if (ESHK(shkp)->surcharge) pacify_shk(shkp);
  81.         } else {
  82.         if (!ESHK(shkp)->surcharge) rile_shk(shkp);
  83.         }
  84.     }
  85.     return(shkp);
  86. }
  87.  
  88. char *
  89. shkname(mtmp)                /* called in do_name.c */
  90. register struct monst *mtmp;
  91. {
  92.     return(ESHK(mtmp)->shknam);
  93. }
  94.  
  95. void
  96. shkgone(mtmp)                /* called in mon.c */
  97. register struct monst *mtmp;
  98. {
  99.     register struct eshk *eshk = ESHK(mtmp);
  100.  
  101.     if(on_level(&(eshk->shoplevel), &u.uz)) {
  102.         remove_damage(mtmp, TRUE);
  103.         rooms[eshk->shoproom - ROOMOFFSET].resident
  104.                           = (struct monst *)0;
  105.         if(!search_special(ANY_SHOP))
  106.             level.flags.has_shop = 0;
  107.     }
  108.     /* make sure bill is set only when the
  109.      * dead shk is the resident shk.    */
  110.     if(*u.ushops == eshk->shoproom) {
  111.         setpaid(mtmp);
  112.         /* dump core when referenced */
  113.         ESHK(mtmp)->bill_p = (struct bill_x *) -1000;
  114.         u.ushops[0] = '\0';
  115.     }
  116. }
  117.  
  118. void
  119. set_residency(shkp, zero_out)
  120. register struct monst *shkp;
  121. register boolean zero_out;
  122. {
  123.     if (on_level(&(ESHK(shkp)->shoplevel), &u.uz))
  124.         rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident =
  125.         (zero_out)? (struct monst *)0 : shkp;
  126. }
  127.  
  128. void
  129. replshk(mtmp,mtmp2)
  130. register struct monst *mtmp, *mtmp2;
  131. {
  132.     rooms[ESHK(mtmp2)->shoproom - ROOMOFFSET].resident = mtmp2;
  133.     if (inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) {
  134.         ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]);
  135.     }
  136. }
  137.  
  138. /* do shopkeeper specific structure munging -dlc */
  139. void
  140. restshk(mtmp, ghostly)
  141. register struct monst *mtmp;
  142. boolean ghostly;
  143. {
  144.     if(u.uz.dlevel) {
  145.     if(ESHK(mtmp)->bill_p != (struct bill_x *) -1000)
  146.         ESHK(mtmp)->bill_p = &(ESHK(mtmp)->bill[0]);
  147.     /* shoplevel can change as dungeons move around */
  148.     /* savebones guarantees that non-homed shk's will be gone */
  149.     if (ghostly)
  150.         assign_level(&(ESHK(mtmp)->shoplevel), &u.uz);
  151.     }
  152. }
  153.  
  154. /* Clear the unpaid bit on all of the objects in the list. */
  155. static void
  156. clear_unpaid(list)
  157. register struct obj *list;
  158. {
  159.     while (list) {
  160.     if (Has_contents(list)) clear_unpaid(list->cobj);
  161.     list->unpaid = 0;
  162.     list = list->nobj;
  163.     }
  164. }
  165.  
  166. STATIC_OVL void
  167. setpaid(shkp)    /* either you paid or left the shop or the shopkeeper died */
  168. register struct monst *shkp;
  169. {
  170.     register struct obj *obj;
  171.     register struct monst *mtmp;
  172.  
  173.     clear_unpaid(invent);
  174.     clear_unpaid(fobj);
  175.     clear_unpaid(level.buriedobjlist);
  176.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  177.         clear_unpaid(mtmp->minvent);
  178.     for(mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
  179.         clear_unpaid(mtmp->minvent);
  180.  
  181.     while ((obj = billobjs) != 0) {
  182.         billobjs = obj->nobj;
  183.         dealloc_obj(obj);
  184.     }
  185.     if(shkp) {
  186.         ESHK(shkp)->billct = 0;
  187.         ESHK(shkp)->credit = 0L;
  188.         ESHK(shkp)->debit = 0L;
  189.         ESHK(shkp)->loan = 0L;
  190.     }
  191. }
  192.  
  193. STATIC_OVL long
  194. addupbill(shkp)
  195. register struct monst *shkp;
  196. {
  197.     register int ct = ESHK(shkp)->billct;
  198.     register struct bill_x *bp = ESHK(shkp)->bill_p;
  199.     register long total = 0L;
  200.  
  201.     while(ct--){
  202.         total += bp->price * bp->bquan;
  203.         bp++;
  204.     }
  205.     return(total);
  206. }
  207.  
  208. #endif /* OVLB */
  209. #ifdef OVL1
  210.  
  211. #ifdef KOPS
  212. STATIC_OVL void
  213. call_kops(shkp, nearshop)
  214. register struct monst *shkp;
  215. register boolean nearshop;
  216. {
  217.     /* Keystone Kops srt@ucla */
  218.     register boolean nokops;
  219.  
  220.     if(!shkp) return;
  221.  
  222.     if (flags.soundok)
  223.         pline("An alarm sounds!");
  224.  
  225.     nokops = ((mons[PM_KEYSTONE_KOP].geno & (G_GENOD | G_EXTINCT)) &&
  226.           (mons[PM_KOP_SERGEANT].geno & (G_GENOD | G_EXTINCT)) &&
  227.           (mons[PM_KOP_LIEUTENANT].geno & (G_GENOD | G_EXTINCT)) &&
  228.           (mons[PM_KOP_KAPTAIN].geno & (G_GENOD | G_EXTINCT)));
  229.  
  230.     if(!angry_guards(!flags.soundok) && nokops) {
  231.         if(flags.verbose && flags.soundok)
  232.         pline("But no one seems to respond to it.");
  233.         return;
  234.     }
  235.  
  236.     if(nokops) return;
  237.  
  238.     {
  239.         coord mm;
  240.  
  241.         if (nearshop) {
  242.         /* Create swarm around you, if you merely "stepped out" */
  243.         if (flags.verbose)
  244.             pline("The Keystone Kops appear!");
  245.         mm.x = u.ux;
  246.         mm.y = u.uy;
  247.         makekops(&mm);
  248.         return;
  249.         }
  250.         if (flags.verbose)
  251.          pline("The Keystone Kops are after you!");
  252.         /* Create swarm near down staircase (hinders return to level) */
  253.         mm.x = xdnstair;
  254.         mm.y = ydnstair;
  255.         makekops(&mm);
  256.         /* Create swarm near shopkeeper (hinders return to shop) */
  257.         mm.x = shkp->mx;
  258.         mm.y = shkp->my;
  259.         makekops(&mm);
  260.     }
  261. }
  262. #endif    /* KOPS */
  263.  
  264. /* x,y is strictly inside shop */
  265. char
  266. inside_shop(x, y)
  267. register xchar x, y;
  268. {
  269.     register char rno;
  270.  
  271.     rno = levl[x][y].roomno;
  272.     if ((rno < ROOMOFFSET) || levl[x][y].edge || !IS_SHOP(rno-ROOMOFFSET))
  273.         return(NO_ROOM);
  274.     else
  275.         return(rno);
  276. }
  277.  
  278. void
  279. u_left_shop(leavestring, newlev)
  280. register char *leavestring;
  281. register boolean newlev;
  282. {
  283.     register struct monst *shkp;
  284.     register struct eshk *eshkp;
  285.     register long total;
  286.  
  287.     /*
  288.      * IF player
  289.      * ((didn't leave outright) AND
  290.      *  ((he is now strictly-inside the shop) OR
  291.      *   (he wasn't strictly-inside last turn anyway)))
  292.      * THEN (there's nothing to do, so just return)
  293.      */
  294.     if(!*leavestring &&
  295.        (!levl[u.ux][u.uy].edge || levl[u.ux0][u.uy0].edge))
  296.         return;
  297.  
  298.     shkp = shop_keeper(*u.ushops0);
  299.  
  300.     if(!shkp || !inhishop(shkp))
  301.                 /* shk died, teleported, changed levels... */
  302.         return;
  303.  
  304.     eshkp = ESHK(shkp);
  305.  
  306.     if(!eshkp->billct && !eshkp->debit)    /* bill is settled */
  307.         return;
  308.  
  309.     if (!*leavestring && shkp->mcanmove && !shkp->msleep) {
  310.         /*
  311.          * Player just stepped onto shop-boundary (known from above logic).
  312.          * Try to intimidate him into paying his bill
  313.          */
  314.         verbalize(NOTANGRY(shkp) ?
  315.               "%s!  Please pay before leaving." :
  316.               "%s!  Don't you leave without paying!",
  317.               plname);
  318.         return;
  319.     }
  320.     total = (addupbill(shkp) + eshkp->debit);
  321.     if (eshkp->credit >= total) {
  322.         Your("credit of %ld zorkmid%s is used to cover your shopping bill.",
  323.          eshkp->credit, plur(eshkp->credit));
  324.         total = 0L;        /* credit gets cleared by setpaid() */
  325.     } else {
  326.         You("escaped the shop without paying!");
  327.         total -= eshkp->credit;
  328.     }
  329.     setpaid(shkp);
  330.     if (!total) return;
  331.  
  332.     /* by this point, we know an actual robbery has taken place */
  333.     eshkp->robbed += total;
  334.     You("stole %ld zorkmid%s worth of merchandise.",
  335.         total, plur(total));
  336.     if (pl_character[0] != 'R') /* stealing is unlawful */
  337.         adjalign(-sgn(u.ualign.type));
  338.  
  339.     hot_pursuit(shkp);
  340. #ifdef KOPS
  341.     call_kops(shkp, (!newlev && levl[u.ux0][u.uy0].edge));
  342. #else
  343.     (void) angry_guards(FALSE);
  344. #endif
  345. }
  346.  
  347. void
  348. u_entered_shop(enterstring)
  349. register char *enterstring;
  350. {
  351.  
  352.     register int rt;
  353.     register struct monst *shkp;
  354.     register struct eshk *eshkp;
  355.     static const char no_shk[] = "This shop appears to be deserted.";
  356.     static char empty_shops[5];
  357.  
  358.     if(!*enterstring)
  359.         return;
  360.  
  361.     if(!(shkp = shop_keeper(*enterstring))) {
  362.         if (!index(empty_shops, *enterstring) &&
  363.         in_rooms(u.ux, u.uy, SHOPBASE) !=
  364.                   in_rooms(u.ux0, u.uy0, SHOPBASE))
  365.         pline(no_shk);
  366.         Strcpy(empty_shops, u.ushops);
  367.         u.ushops[0] = '\0';
  368.         return;
  369.     }
  370.  
  371.     eshkp = ESHK(shkp);
  372.  
  373.     if (!inhishop(shkp)) {
  374.         /* dump core when referenced */
  375.         eshkp->bill_p = (struct bill_x *) -1000;
  376.         if (!index(empty_shops, *enterstring))
  377.         pline(no_shk);
  378.         Strcpy(empty_shops, u.ushops);
  379.         u.ushops[0] = '\0';
  380.         return;
  381.     }
  382.  
  383.     eshkp->bill_p = &(eshkp->bill[0]);
  384.  
  385.     if (!eshkp->visitct || strncmpi(eshkp->customer, plname, PL_NSIZ)) {
  386.         /* You seem to be new here */
  387.         eshkp->visitct = 0;
  388.         eshkp->following = 0;
  389.         (void) strncpy(eshkp->customer,plname,PL_NSIZ);
  390.         pacify_shk(shkp);
  391.     }
  392.  
  393.     if (shkp->msleep || !shkp->mcanmove || eshkp->following) /* no dialog */
  394.         return;
  395.  
  396.     if (Invis) {
  397.         pline("%s senses your presence.", shkname(shkp));
  398.         verbalize("Invisible customers are not welcome!");
  399.         return;
  400.     }
  401.  
  402.     rt = rooms[*enterstring - ROOMOFFSET].rtype;
  403.  
  404.     if (ANGRY(shkp)) {
  405.         verbalize("So, %s, you dare return to %s %s?!",
  406.               plname,
  407.               s_suffix(shkname(shkp)),
  408.               shtypes[rt - SHOPBASE].name);
  409.     } else if (eshkp->robbed) {
  410.         pline("%s mutters imprecations against shoplifters.", shkname(shkp));
  411.     } else {
  412.         verbalize("Hello, %s!  Welcome%s to %s %s!",
  413.               plname,
  414.               eshkp->visitct++ ? " again" : "",
  415.               s_suffix(shkname(shkp)),
  416.               shtypes[rt - SHOPBASE].name);
  417.     }
  418.     if(carrying(PICK_AXE) != (struct obj *)0 &&
  419.                  /* can't do anything if teleported in */
  420.                  !inside_shop(u.ux, u.uy)) {
  421.         verbalize(NOTANGRY(shkp) ?
  422.               "Will you please leave your pick-axe outside?" :
  423.               "Leave the pick-axe outside.");
  424.         (void) dochug(shkp);
  425.     }
  426.     return;
  427. }
  428.  
  429. /*
  430.    Decide whether two unpaid items are mergable; caller is responsible for
  431.    making sure they're unpaid and the same type of object; we check the price
  432.    quoted by the shopkeeper and also that they both belong to the same shk.
  433.  */
  434. boolean same_price(obj1, obj2)
  435. struct obj *obj1, *obj2;
  436. {
  437.     register struct monst *shkp1, *shkp2;
  438.     register struct bill_x *bp1 = 0, *bp2 = 0;
  439.     register boolean are_mergable = FALSE;
  440.  
  441.     /* look up the first object by finding shk whose bill it's on */
  442.     for (shkp1 = next_shkp(fmon, TRUE); shkp1;
  443.         shkp1 = next_shkp(shkp1, TRUE))
  444.         if ((bp1 = onbill(obj1, shkp1, TRUE)) != 0) break;
  445.     /* second object is probably owned by same shk; if not, look harder */
  446.     if (shkp1 && (bp2 = onbill(obj2, shkp1, TRUE)) != 0) {
  447.         shkp2 = shkp1;
  448.     } else {
  449.         for (shkp2 = next_shkp(fmon, TRUE); shkp2;
  450.             shkp2 = next_shkp(shkp2, TRUE))
  451.         if ((bp2 = onbill(obj2, shkp2, TRUE)) != 0) break;
  452.     }
  453.  
  454.     if (!bp1 || !bp2) impossible("same_price: object wasn't on any bill!");
  455.     else are_mergable = (shkp1 == shkp2 && bp1->price == bp2->price);
  456.     return are_mergable;
  457. }
  458.  
  459. #endif /* OVL1 */
  460. #ifdef OVLB
  461.  
  462. int
  463. inhishop(mtmp)
  464. register struct monst *mtmp;
  465. {
  466.     return(index(in_rooms(mtmp->mx, mtmp->my, SHOPBASE),
  467.              ESHK(mtmp)->shoproom) &&
  468.         on_level(&(ESHK(mtmp)->shoplevel), &u.uz));
  469. }
  470.  
  471. struct monst *
  472. shop_keeper(rmno)
  473. register char rmno;
  474. {
  475.     struct monst *shkp = rmno >= ROOMOFFSET ?
  476.                 rooms[rmno - ROOMOFFSET].resident : 0;
  477.  
  478.     if (shkp) {
  479.         if (NOTANGRY(shkp)) {
  480.         if (ESHK(shkp)->surcharge) pacify_shk(shkp);
  481.         } else {
  482.         if (!ESHK(shkp)->surcharge) rile_shk(shkp);
  483.         }
  484.     }
  485.     return shkp;
  486. }
  487.  
  488. #ifdef SOUNDS
  489. boolean
  490. tended_shop(sroom)
  491. register struct mkroom *sroom;
  492. {
  493.     register struct monst *mtmp = sroom->resident;
  494.  
  495.     if (!mtmp)
  496.         return(FALSE);
  497.     else
  498.         return((boolean)(inhishop(mtmp)));
  499. }
  500. #endif    /* SOUNDS */
  501.  
  502. static struct bill_x *
  503. onbill(obj, shkp, silent)
  504. register struct obj *obj;
  505. register struct monst *shkp;
  506. register boolean silent;
  507. {
  508.     if (shkp) {
  509.         register struct bill_x *bp = ESHK(shkp)->bill_p;
  510.         register int ct = ESHK(shkp)->billct;
  511.  
  512.         while (--ct >= 0)
  513.             if (bp->bo_id == obj->o_id) {
  514.             if (!obj->unpaid) pline("onbill: paid obj on bill?");
  515.             return bp;
  516.             } else bp++;
  517.     }
  518.     if(obj->unpaid & !silent) pline("onbill: unpaid obj not on bill?");
  519.     return (struct bill_x *)0;
  520. }
  521.  
  522. /* Delete the contents of the given object. */
  523. void
  524. delete_contents(obj)
  525. register struct obj *obj;
  526. {
  527.     register struct obj *curr, *next;
  528.  
  529.     for (curr = obj->cobj; curr; curr = next) {
  530.         next = curr->nobj;
  531.         obfree(curr, (struct obj *)0);
  532.     }
  533.     obj->cobj = (struct obj *) 0;
  534. }
  535.  
  536. /* called with two args on merge */
  537. void
  538. obfree(obj, merge)
  539. register struct obj *obj, *merge;
  540. {
  541.     register struct bill_x *bp;
  542.     register struct bill_x *bpm;
  543.     register struct monst *shkp;
  544.  
  545.     if(obj->oclass == FOOD_CLASS) food_disappears(obj);
  546.  
  547.     if (obj->cobj) delete_contents(obj);
  548.  
  549.     shkp = shop_keeper(*u.ushops);
  550.  
  551.     if ((bp = onbill(obj, shkp, FALSE)) != 0) {
  552.         if(!merge){
  553.             bp->useup = 1;
  554.             obj->unpaid = 0;    /* only for doinvbill */
  555.             obj->nobj = billobjs;
  556.             billobjs = obj;
  557.             return;
  558.         }
  559.         bpm = onbill(merge, shkp, FALSE);
  560.         if(!bpm){
  561.             /* this used to be a rename */
  562.             impossible("obfree: not on bill??");
  563.             return;
  564.         } else {
  565.             /* this was a merger */
  566.             bpm->bquan += bp->bquan;
  567.             ESHK(shkp)->billct--;
  568. #ifdef DUMB
  569.             {
  570.             /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  571.                 int indx = ESHK(shkp)->billct;
  572.                 *bp = ESHK(shkp)->bill_p[indx];
  573.             }
  574. #else
  575.             *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
  576. #endif
  577.         }
  578.     }
  579.     dealloc_obj(obj);
  580. }
  581.  
  582. static long
  583. check_credit(tmp, shkp)
  584. long tmp;
  585. register struct monst *shkp;
  586. {
  587.     long credit = ESHK(shkp)->credit;
  588.  
  589.     if(credit == 0L) return(tmp);
  590.     if(credit >= tmp) {
  591.         pline("The price is deducted from your credit.");
  592.         ESHK(shkp)->credit -=tmp;
  593.         tmp = 0L;
  594.     } else {
  595.         pline("The price is partially covered by your credit.");
  596.         ESHK(shkp)->credit = 0L;
  597.         tmp -= credit;
  598.     }
  599.     return(tmp);
  600. }
  601.  
  602. static void
  603. pay(tmp,shkp)
  604. long tmp;
  605. register struct monst *shkp;
  606. {
  607.     long robbed = ESHK(shkp)->robbed;
  608.     long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
  609.  
  610.     u.ugold -= balance;
  611.     shkp->mgold += balance;
  612.     flags.botl = 1;
  613.     if(robbed) {
  614.         robbed -= tmp;
  615.         if(robbed < 0) robbed = 0L;
  616.         ESHK(shkp)->robbed = robbed;
  617.     }
  618. }
  619.  
  620. /* return shkp to home position */
  621. void
  622. home_shk(shkp, killkops)
  623. register struct monst *shkp;
  624. register boolean killkops;
  625. {
  626.     register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
  627.  
  628.     (void) mnearto(shkp, x, y, TRUE);
  629.     level.flags.has_shop = 1;
  630.     if (killkops) {
  631. #ifdef KOPS
  632.         kops_gone(TRUE);
  633. #else
  634.         You("feel vaguely apprehensive.");
  635. #endif
  636.         pacify_guards();
  637.     }
  638. }
  639.  
  640. static boolean
  641. angry_shk_exists()
  642. {
  643.     register struct monst *shkp;
  644.  
  645.     for (shkp = next_shkp(fmon, FALSE);
  646.         shkp; shkp = next_shkp(shkp->nmon, FALSE))
  647.         if (ANGRY(shkp)) return(TRUE);
  648.     return(FALSE);
  649. }
  650.  
  651. /* remove previously applied surcharge from all billed items */
  652. STATIC_OVL void
  653. pacify_shk(shkp)
  654. register struct monst *shkp;
  655. {
  656.     NOTANGRY(shkp) = TRUE;    /* make peaceful */
  657.     if (ESHK(shkp)->surcharge) {
  658.         register struct bill_x *bp = ESHK(shkp)->bill_p;
  659.         register int ct = ESHK(shkp)->billct;
  660.  
  661.         ESHK(shkp)->surcharge = FALSE;
  662.         while (ct-- > 0) {
  663.             register long reduction = (bp->price + 3L) / 4L;
  664.             bp->price -= reduction;        /* undo 33% increase */
  665.             bp++;
  666.         }
  667.     }
  668. }
  669.  
  670. /* add aggravation surcharge to all billed items */
  671. static void
  672. rile_shk(shkp)
  673. register struct monst *shkp;
  674. {
  675.     NOTANGRY(shkp) = FALSE;    /* make angry */
  676.     if (!ESHK(shkp)->surcharge) {
  677.         register struct bill_x *bp = ESHK(shkp)->bill_p;
  678.         register int ct = ESHK(shkp)->billct;
  679.  
  680.         ESHK(shkp)->surcharge = TRUE;
  681.         while (ct-- > 0) {
  682.             register long surcharge = (bp->price + 2L) / 3L;
  683.             bp->price += surcharge;
  684.             bp++;
  685.         }
  686.     }
  687. }
  688.  
  689. void
  690. make_happy_shk(shkp, silentkops)
  691. register struct monst *shkp;
  692. register boolean silentkops;
  693. {
  694.     register boolean wasmad = ANGRY(shkp);
  695.  
  696.     pacify_shk(shkp);
  697.     ESHK(shkp)->following = 0;
  698.     ESHK(shkp)->robbed = 0L;
  699.     if (pl_character[0] != 'R')
  700.         adjalign(sgn(u.ualign.type));
  701.     if(!inhishop(shkp)) {
  702.         pline("Satisfied, %s suddenly disappears!", mon_nam(shkp));
  703.         if(on_level(&(ESHK(shkp)->shoplevel), &u.uz))
  704.             home_shk(shkp, FALSE);
  705.         else
  706.             migrate_to_level(shkp,
  707.                  ledger_no(&(ESHK(shkp)->shoplevel)), 0);
  708.     } else if(wasmad)
  709.         pline("%s calms down.", Monnam(shkp));
  710.  
  711.     if(!angry_shk_exists()) {
  712. #ifdef KOPS
  713.         kops_gone(silentkops);
  714. #endif
  715.         pacify_guards();
  716.     }
  717. }
  718.  
  719. void
  720. hot_pursuit(shkp)
  721. register struct monst *shkp;
  722. {
  723.     if(!shkp->isshk) return;
  724.  
  725.     rile_shk(shkp);
  726.     ESHK(shkp)->following = 1;
  727. }
  728.  
  729. /* used when the shkp is teleported out of his shop,
  730.  * or when the player is not on a costly_spot and he
  731.  * damages something inside the shop.  these conditions
  732.  * must be checked by the calling function.
  733.  */
  734. void
  735. make_angry_shk(shkp, ox, oy)
  736. register struct monst *shkp;
  737. register xchar ox,oy;
  738. {
  739.     if(index(in_rooms(ox, oy, SHOPBASE), ESHK(shkp)->shoproom) &&
  740.         !ANGRY(shkp)) {
  741.         ESHK(shkp)->robbed += (addupbill(shkp) +
  742.                        ESHK(shkp)->debit + ESHK(shkp)->loan);
  743.         ESHK(shkp)->robbed -= ESHK(shkp)->credit;
  744.         if(ESHK(shkp)->robbed < 0L)
  745.             ESHK(shkp)->robbed = 0L;
  746.         ESHK(shkp)->credit = 0L;
  747.         setpaid(shkp);
  748.     }
  749.     if(!ANGRY(shkp)) pline("%s gets angry!", Monnam(shkp));
  750.     else pline("%s is furious!", Monnam(shkp));
  751.     hot_pursuit(shkp);
  752. }
  753.  
  754. static const char no_money[] = "Moreover, you%s have no money.";
  755.  
  756. static long
  757. cheapest_item(shkp)   /* delivers the cheapest item on the list */
  758. register struct monst *shkp;
  759. {
  760.     register int ct = ESHK(shkp)->billct;
  761.     register struct bill_x *bp = ESHK(shkp)->bill_p;
  762.     register long gmin = (bp->price * bp->bquan);
  763.  
  764.     while(ct--){
  765.         if(bp->price * bp->bquan < gmin)
  766.             gmin = bp->price * bp->bquan;
  767.         bp++;
  768.     }
  769.     return(gmin);
  770. }
  771.  
  772. int
  773. dopay()
  774. {
  775.     long ltmp;
  776.     register struct monst *nxtm = (struct monst *)0;
  777.     register struct monst *shkp, *resident = (struct monst *)0;
  778.     register struct eshk *eshkp;
  779.     int pass, tmp, sk = 0, seensk = 0;
  780.     register boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L);
  781.  
  782.     multi = 0;
  783.  
  784.     /* find how many shk's there are, how many are in */
  785.     /* sight, and are you in a shop room with one.    */
  786.     for (shkp = next_shkp(fmon, FALSE);
  787.         shkp; shkp = next_shkp(shkp->nmon, FALSE)) {
  788.         sk++;
  789.         if (ANGRY(shkp) && distu(shkp->mx, shkp->my) <= 2) nxtm = shkp;
  790.         if (canseemon(shkp) || sensemon(shkp)) seensk++;
  791.         if (inhishop(shkp) && (*u.ushops == ESHK(shkp)->shoproom))
  792.         resident = shkp;
  793.     }
  794.  
  795.     if (nxtm) {            /* Player should always appease an */
  796.          shkp = nxtm;        /* irate shk standing next to them. */
  797.          goto proceed;
  798.     }
  799.  
  800.     if ((!sk && (!Blind || Telepat)) || (!Blind && !seensk)) {
  801.       pline("There appears to be no shopkeeper here to receive your payment.");
  802.         return(0);
  803.     }
  804.  
  805.     if(!seensk) {
  806.         You("can't see...");
  807.         return(0);
  808.     }
  809.  
  810.     /* the usual case.  allow paying at a distance when */
  811.     /* inside a tended shop.  should we change that?    */
  812.     if(sk == 1 && resident) {
  813.         shkp = resident;
  814.         goto proceed;
  815.     }
  816.  
  817.     if (seensk == 1) {
  818.         for (shkp = next_shkp(fmon, FALSE);
  819.             shkp; shkp = next_shkp(shkp->nmon, FALSE))
  820.             if (canseemon(shkp) || sensemon(shkp)) break;
  821.         if (shkp != resident && distu(shkp->mx, shkp->my) > 2) {
  822.             pline("%s is not near enough to receive your payment.",
  823.                          Monnam(shkp));
  824.             return(0);
  825.         }
  826.     } else {
  827.         struct monst *mtmp;
  828.         coord cc;
  829.         int cx, cy;
  830.  
  831.         pline("Pay whom?");
  832.         cc.x = u.ux;
  833.         cc.y = u.uy;
  834.         getpos(&cc, TRUE, "the creature you want to pay");
  835.         cx = cc.x;
  836.         cy = cc.y;
  837.         if(cx == -10) return(0); /* player pressed esc */
  838.         if(cx < 0) {
  839.              pline("Try again...");
  840.              return(0);
  841.         }
  842.         if(u.ux == cx && u.uy == cy) {
  843.              You("are generous to yourself.");
  844.              return(0);
  845.         }
  846.         mtmp = m_at(cx, cy);
  847.         if(!mtmp) {
  848.              pline("There is no one there to receive your payment.");
  849.              return(0);
  850.         }
  851.         if(!mtmp->isshk) {
  852.              pline("%s is not interested in your payment.",
  853.                     Monnam(mtmp));
  854.              return(0);
  855.         }
  856.         if (mtmp != resident && distu(mtmp->mx, mtmp->my) > 2) {
  857.              pline("%s is too far to receive your payment.",
  858.                     Monnam(mtmp));
  859.              return(0);
  860.         }
  861.         shkp = mtmp;
  862.     }
  863.  
  864.     if(!shkp) {
  865. #ifdef DEBUG
  866.         pline("dopay: null shkp.");
  867. #endif
  868.         return(0);
  869.     }
  870. proceed:
  871.  
  872.     if (shkp->msleep || !shkp->mcanmove) {
  873.         pline("%s %s.", Monnam(shkp),
  874.               rn2(2) ? "seems to be napping" : "doesn't respond");
  875.         return 0;
  876.     }
  877.     eshkp = ESHK(shkp);
  878.  
  879.     ltmp = eshkp->robbed;
  880.     if(shkp != resident && NOTANGRY(shkp)) {
  881.         if(!ltmp)
  882.             You("do not owe %s anything.", mon_nam(shkp));
  883.         else if(!u.ugold) {
  884.             You("%shave no money.", stashed_gold ? "seem to " : "");
  885.             if(stashed_gold)
  886.             pline("But you have some gold stashed away.");
  887.         } else {
  888.             const char *pronoun = shkp->female ? "she" : "he";
  889.             long ugold = u.ugold;
  890.  
  891.             if(ugold > ltmp) {
  892.             You("give %s the %ld gold piece%s %s asked for.",
  893.                 mon_nam(shkp), ltmp, plur(ltmp), pronoun);
  894.             pay(ltmp, shkp);
  895.             } else {
  896.             You("give %s all your%s gold.", mon_nam(shkp),
  897.                     stashed_gold ? " openly kept" : "");
  898.             pay(u.ugold, shkp);
  899.             if (stashed_gold) pline("But you have hidden gold!");
  900.             }
  901.             if((ugold < ltmp/2L) || (ugold < ltmp && stashed_gold))
  902.             pline("Unfortunately, %s doesn't look satisfied.",
  903.                 pronoun);
  904.             else
  905.             make_happy_shk(shkp, FALSE);
  906.         }
  907.         return(1);
  908.     }
  909.  
  910.     /* ltmp is still eshkp->robbed here */
  911.     if (!eshkp->billct && !eshkp->debit) {
  912.         const char *pronoun = him[shkp->female];
  913.         const char *possessive = his[shkp->female];
  914.  
  915.         if(!ltmp && NOTANGRY(shkp)) {
  916.             You("do not owe %s anything.", mon_nam(shkp));
  917.             if(!u.ugold) pline(no_money, stashed_gold ?
  918.                        " seem to" : "");
  919.         } else if(ltmp) {
  920.             pline("%s is after blood, not money!", Monnam(shkp));
  921.             if(u.ugold < ltmp/2L ||
  922.                 (u.ugold < ltmp && stashed_gold)) {
  923.             if(!u.ugold) pline(no_money, stashed_gold ?
  924.                                " seem to" : "");
  925.             else pline("Besides, you don't have enough to interest %s.",
  926.                 pronoun);
  927.             return(1);
  928.             }
  929.             pline("But since %s shop has been robbed recently,",
  930.             possessive);
  931.             pline("you %scompensate %s for %s losses.",
  932.             (u.ugold < ltmp) ? "partially " : "",
  933.             mon_nam(shkp), possessive);
  934.             pay(u.ugold < ltmp ? u.ugold : ltmp, shkp);
  935.             make_happy_shk(shkp, FALSE);
  936.         } else {
  937.             /* shopkeeper is angry, but has not been robbed --
  938.              * door broken, attacked, etc. */
  939.             pline("%s is after your hide, not your money!",
  940.                              mon_nam(shkp));
  941.             if(u.ugold < 1000L) {
  942.             if(!u.ugold) pline(no_money, stashed_gold ?
  943.                          " seem to" : "");
  944.             else pline("Besides, you don't have enough to interest %s.",
  945.                     pronoun);
  946.             return(1);
  947.             }
  948.             You("try to appease %s by giving %s 1000 gold pieces.",
  949.             x_monnam(shkp, 1, "angry", 0), pronoun);
  950.             pay(1000L,shkp);
  951.             if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3))
  952.             make_happy_shk(shkp, FALSE);
  953.             else
  954.             pline("But %s is as angry as ever.", mon_nam(shkp));
  955.         }
  956.         return(1);
  957.     }
  958.     if(shkp != resident) {
  959.         impossible("dopay: not to shopkeeper?");
  960.         if(resident) setpaid(resident);
  961.         return(0);
  962.     }
  963.     /* pay debt, if any, first */
  964.     if(eshkp->debit) {
  965.         long dtmp = eshkp->debit;
  966.         long loan = eshkp->loan;
  967.         char sbuf[BUFSZ];
  968.  
  969.         Sprintf(sbuf, "You owe %s %ld zorkmid%s ",
  970.                        shkname(shkp), dtmp, plur(dtmp));
  971.         if(loan) {
  972.             if(loan == dtmp)
  973.             Strcat(sbuf, "you picked up in the store.");
  974.             else Strcat(sbuf,
  975.                "for gold picked up and the use of merchandise.");
  976.         } else Strcat(sbuf, "for the use of merchandise.");
  977.         pline(sbuf);
  978.         if (u.ugold + eshkp->credit < dtmp) {
  979.             pline("But you don't%s have enough gold%s.",
  980.             stashed_gold ? " seem to" : "",
  981.             eshkp->credit ? " or credit" : "");
  982.             return(1);
  983.         } else {
  984.             if (eshkp->credit >= dtmp) {
  985.             eshkp->credit -= dtmp;
  986.             eshkp->debit = 0L;
  987.             eshkp->loan = 0L;
  988.             Your("debt is covered by your credit.");
  989.             } else if (!eshkp->credit) {
  990.             u.ugold -= dtmp;
  991.             shkp->mgold += dtmp;
  992.             eshkp->debit = 0L;
  993.             eshkp->loan = 0L;
  994.             You("pay that debt.");
  995.             flags.botl = 1;
  996.             } else {
  997.             dtmp -= eshkp->credit;
  998.             eshkp->credit = 0L;
  999.             u.ugold -= dtmp;
  1000.             shkp->mgold += dtmp;
  1001.             eshkp->debit = 0L;
  1002.             eshkp->loan = 0L;
  1003.             pline("That debt is partially offset by your credit.");
  1004.             You("pay the remainder.");
  1005.             flags.botl = 1;
  1006.             }
  1007.             paid = TRUE;
  1008.         }
  1009.     }
  1010.     /* now check items on bill */
  1011.     if (eshkp->billct) {
  1012.         register boolean itemize;
  1013.  
  1014.         if (!u.ugold && !eshkp->credit) {
  1015.         You("%shave no money or credit%s.",
  1016.                     stashed_gold ? "seem to " : "",
  1017.                     paid ? " left" : "");
  1018.         return(0);
  1019.         }
  1020.         if ((u.ugold + eshkp->credit) < cheapest_item(shkp)) {
  1021.         You("don't have enough money to buy%s the item%s you picked.",
  1022.             eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct));
  1023.         if(stashed_gold)
  1024.             pline("Maybe you have some gold stashed away?");
  1025.         return(0);
  1026.         }
  1027.  
  1028.         /* this isn't quite right; it itemizes without asking if the
  1029.          * single item on the bill is partly used up and partly unpaid */
  1030.         itemize = (eshkp->billct > 1 ? yn("Itemized billing?") == 'y' : 1);
  1031.  
  1032.         for (pass = 0; pass <= 1; pass++) {
  1033.         tmp = 0;
  1034.         while (tmp < eshkp->billct) {
  1035.             struct obj *otmp;
  1036.             register struct bill_x *bp = &(eshkp->bill_p[tmp]);
  1037.  
  1038.             /* find the object on one of the lists */
  1039.             if ((otmp = bp_to_obj(bp)) != 0) {
  1040.             /* if completely used up, object quantity is stale;
  1041.                restoring it to its original value here avoids
  1042.                making the partly-used-up code more complicated */
  1043.             if (bp->useup) otmp->quan = bp->bquan;
  1044.             } else {
  1045.             impossible("Shopkeeper administration out of order.");
  1046.             setpaid(shkp);    /* be nice to the player */
  1047.             return 1;
  1048.             }
  1049.             if (pass == bp->useup && otmp->quan == bp->bquan) {
  1050.             /* pay for used-up items on first pass and others
  1051.              * on second, so player will be stuck in the store
  1052.              * less often; things which are partly used up
  1053.              * are processed on both passes */
  1054.             tmp++;
  1055.             } else {
  1056.             switch (dopayobj(shkp, bp, &otmp, pass, itemize)) {
  1057.               case PAY_CANT:
  1058.                 return 1;    /*break*/
  1059.               case PAY_BROKE:
  1060.                 paid = TRUE;
  1061.                 goto thanks;    /*break*/
  1062.               case PAY_SKIP:
  1063.                 tmp++;
  1064.                 continue;    /*break*/
  1065.               case PAY_SOME:
  1066.                 paid = TRUE;
  1067.                 if (itemize) bot();
  1068.                 continue;    /*break*/
  1069.               case PAY_BUY:
  1070.                 paid = TRUE;
  1071.                 break;
  1072.             }
  1073.             if (itemize) bot();
  1074.             *bp = eshkp->bill_p[--eshkp->billct];
  1075.             }
  1076.         }
  1077.         }
  1078.     }
  1079. thanks:
  1080.     if(!ANGRY(shkp) && paid)
  1081.         verbalize("Thank you for shopping in %s %s!",
  1082.         s_suffix(shkname(shkp)),
  1083.         shtypes[rooms[eshkp->shoproom - ROOMOFFSET].rtype - SHOPBASE].name);
  1084.     return(1);
  1085. }
  1086.  
  1087. /* return 2 if used-up portion paid */
  1088. /*      1 if paid successfully    */
  1089. /*      0 if not enough money     */
  1090. /*     -1 if skip this object     */
  1091. /*     -2 if no money/credit left */
  1092. static int
  1093. dopayobj(shkp, bp, obj_p, which, itemize)
  1094. register struct monst *shkp;
  1095. register struct bill_x *bp;
  1096. struct obj **obj_p;
  1097. int    which;        /* 0 => used-up item, 1 => other (unpaid or lost) */
  1098. boolean itemize;
  1099. {
  1100.     register struct obj *obj = *obj_p;
  1101.     long ltmp, quan, save_quan;
  1102.     int buy;
  1103.     boolean stashed_gold = (hidden_gold() > 0L),
  1104.         consumed = (which == 0);
  1105.  
  1106.     if(!obj->unpaid && !bp->useup){
  1107.         impossible("Paid object on bill??");
  1108.         return PAY_BUY;
  1109.     }
  1110.     if(itemize && u.ugold + ESHK(shkp)->credit == 0L){
  1111.         You("%shave no money or credit left.",
  1112.                  stashed_gold ? "seem to " : "");
  1113.         return PAY_BROKE;
  1114.     }
  1115.     /* we may need to temporarily adjust the object, if part of the
  1116.        original quantity has been used up but part remains unpaid  */
  1117.     save_quan = obj->quan;
  1118.     if (consumed) {
  1119.         /* either completely used up (simple), or split needed */
  1120.         quan = bp->bquan;
  1121.         if (quan > obj->quan)    /* difference is amount used up */
  1122.         quan -= obj->quan;
  1123.     } else {
  1124.         /* dealing with ordinary unpaid item */
  1125.         quan = obj->quan;
  1126.     }
  1127.     obj->quan = quan;    /* to be used by doname() */
  1128.     obj->unpaid = 0;    /* ditto */
  1129.     ltmp = bp->price * quan;
  1130.     buy = PAY_BUY;        /* flag; if changed then return early */
  1131.  
  1132.     if (itemize) {
  1133.         char qbuf[BUFSZ];
  1134.         Sprintf(qbuf,"%s for %ld zorkmid%s.  Pay?", quan == 1L ?
  1135.             Doname2(obj) : doname(obj), ltmp, plur(ltmp));
  1136.         if (yn(qbuf) == 'n') {
  1137.         buy = PAY_SKIP;        /* don't want to buy */
  1138.         } else if (quan < bp->bquan && !consumed) { /* partly used goods */
  1139.         obj->quan = bp->bquan - save_quan;    /* used up amount */
  1140.         verbalize("%s for the other %s before buying %s.",
  1141.               ANGRY(shkp) ? "Pay" : "Please pay", xname(obj),
  1142.               save_quan > 1L ? "these" : "this one");
  1143.         buy = PAY_SKIP;        /* shk won't sell */
  1144.         }
  1145.     }
  1146.     if (buy == PAY_BUY && u.ugold + ESHK(shkp)->credit < ltmp) {
  1147.         You("don't%s have gold%s enough to pay for %s.",
  1148.         stashed_gold ? " seem to" : "",
  1149.         (ESHK(shkp)->credit > 0L) ? " or credit" : "",
  1150.         doname(obj));
  1151.         buy = itemize ? PAY_SKIP : PAY_CANT;
  1152.     }
  1153.  
  1154.     if (buy != PAY_BUY) {
  1155.         /* restore unpaid object to original state */
  1156.         obj->quan = save_quan;
  1157.         obj->unpaid = 1;
  1158.         return buy;
  1159.     }
  1160.  
  1161.     pay(ltmp, shkp);
  1162.     shk_names_obj(obj);    /* identify some non-magic objects */
  1163.     You("bought %s for %ld gold piece%s.",
  1164.         doname(obj), ltmp, plur(ltmp));
  1165.     obj->quan = save_quan;        /* restore original count */
  1166.     /* quan => amount just bought, save_quan => remaining unpaid count */
  1167.     if (consumed) {
  1168.         if (quan != bp->bquan) {
  1169.         /* eliminate used-up portion; remainder is still unpaid */
  1170.         bp->bquan = obj->quan;
  1171.         obj->unpaid = 1;
  1172.         bp->useup = 0;
  1173.         buy = PAY_SOME;
  1174.         } else {    /* completely used-up, so get rid of it */
  1175.         if (obj == billobjs) {
  1176.             billobjs = obj->nobj;
  1177.         } else {
  1178.             register struct obj *otmp = billobjs;
  1179.  
  1180.             while (otmp && otmp->nobj != obj) otmp = otmp->nobj;
  1181.             if (otmp) otmp->nobj = obj->nobj;
  1182.             else impossible("Error in shopkeeper administration.");
  1183.         }
  1184.          /* assert( obj == *obj_p ); */
  1185.         dealloc_obj(obj);
  1186.         *obj_p = 0;    /* destroy pointer to freed object */
  1187.         }
  1188.     }
  1189.     return buy;
  1190. }
  1191.  
  1192. /* routine called after dying (or quitting) */
  1193. boolean
  1194. paybill(croaked)
  1195. register boolean croaked;
  1196. {
  1197.     register struct monst *mtmp, *mtmp2, *resident= (struct monst *)0;
  1198.     register boolean taken = FALSE;
  1199.     register int numsk = 0;
  1200.  
  1201.     /* give shopkeeper first crack */
  1202.     if ((mtmp = shop_keeper(*u.ushops)) && inhishop(mtmp)) {
  1203.         numsk++;
  1204.         resident = mtmp;
  1205.         taken = inherits(resident, numsk, croaked);
  1206.     }
  1207.     for (mtmp = next_shkp(fmon, FALSE);
  1208.         mtmp; mtmp = next_shkp(mtmp2, FALSE)) {
  1209.         mtmp2 = mtmp->nmon;
  1210.         if (mtmp != resident) {
  1211.         /* for bones: we don't want a shopless shk around */
  1212.         if(!on_level(&(ESHK(mtmp)->shoplevel), &u.uz))
  1213.             mongone(mtmp);
  1214.         else {
  1215.             numsk++;
  1216.             taken |= inherits(mtmp, numsk, croaked);
  1217.         }
  1218.         }
  1219.     }
  1220.     if(numsk == 0) return(FALSE);
  1221.     return(taken);
  1222. }
  1223.  
  1224. static boolean
  1225. inherits(shkp, numsk, croaked)
  1226. register struct monst *shkp;
  1227. register int numsk;
  1228. register boolean croaked;
  1229. {
  1230.     register long loss = 0L;
  1231.     register struct obj *otmp;
  1232.     register struct eshk *eshkp = ESHK(shkp);
  1233.     register xchar ox, oy;
  1234.     register boolean take = FALSE, taken = FALSE;
  1235.     register int roomno = *u.ushops;
  1236.  
  1237.     /* the simplifying principle is that first-come */
  1238.     /* already took everything you had.        */
  1239.     if(numsk > 1) {
  1240.         if(cansee(shkp->mx, shkp->my) && croaked)
  1241.         pline("%s %slooks at your corpse%s%s", Monnam(shkp),
  1242.              (shkp->msleep || !shkp->mcanmove) ?
  1243.                    "wakes up, " : "",
  1244.              !rn2(2) ? (shkp->female ? ", shakes her head," :
  1245.                  ", shakes his head,") : "",
  1246.              !inhishop(shkp) ? " and disappears. " : " and sighs.");
  1247.         taken = (roomno == eshkp->shoproom);
  1248.         goto skip;
  1249.     }
  1250.  
  1251.     /* get one case out of the way: you die in the shop, the */
  1252.     /* shopkeeper is peaceful, nothing stolen, nothing owed. */
  1253.     if(roomno == eshkp->shoproom && inhishop(shkp) &&
  1254.         !IS_DOOR(levl[u.ux][u.uy].typ) && !eshkp->billct &&
  1255.         !eshkp->robbed && !eshkp->debit &&
  1256.          NOTANGRY(shkp) && !eshkp->following) {
  1257.         if (invent)
  1258.             pline("%s gratefully inherits all your possessions.",
  1259.                 shkname(shkp));
  1260.         goto clear;
  1261.     }
  1262.  
  1263.     if (eshkp->billct || eshkp->debit || eshkp->robbed) {
  1264.         register long total = 0L;
  1265.  
  1266.         if(roomno == eshkp->shoproom && inhishop(shkp))
  1267.             total = (addupbill(shkp) + eshkp->debit);
  1268.         loss = ((total >= eshkp->robbed) ? total : eshkp->robbed);
  1269.         take = TRUE;
  1270.     }
  1271.  
  1272.     if (eshkp->following || ANGRY(shkp) || take) {
  1273.  
  1274.         if(!invent && !u.ugold) goto skip;
  1275.  
  1276.         if((loss > u.ugold) || !loss) {
  1277.             pline("%s %s%stakes all your possessions.",
  1278.                 shkname(shkp),
  1279.                 (shkp->msleep || !shkp->mcanmove) ?
  1280.                    "wakes up and " : "",
  1281.                 (distu(shkp->mx, shkp->my) > 2) ?
  1282.                     "comes and " : "");
  1283.             taken = TRUE;
  1284.             shkp->mgold += u.ugold;
  1285.             u.ugold = 0L;
  1286.             /* in case bones: make it be for real... */
  1287.             if(!*u.ushops ||
  1288.                  IS_DOOR(levl[u.ux][u.uy].typ)) {
  1289.                 /* shk.x,shk.y is the position immediately in
  1290.                  * front of the door -- move in one more space
  1291.                  */
  1292.                 ox = eshkp->shk.x;
  1293.                 oy = eshkp->shk.y;
  1294.                 ox += sgn(ox - eshkp->shd.x);
  1295.                 oy += sgn(oy - eshkp->shd.y);
  1296.             } else {
  1297.                 ox = u.ux;
  1298.                 oy = u.uy;
  1299.             }
  1300.  
  1301.             if (invent) {
  1302.                 for(otmp = invent; otmp; otmp = otmp->nobj)
  1303.                 place_object(otmp, ox, oy);
  1304.  
  1305.                 /* add to main object list at end so invent is
  1306.                    still good */
  1307.                 if (fobj) {
  1308.                 otmp = fobj;
  1309.                 while(otmp->nobj)
  1310.                     otmp = otmp->nobj;
  1311.                 otmp->nobj = invent;
  1312.                 } else
  1313.                 fobj = invent;
  1314.             }
  1315.         } else {
  1316.             u.ugold -= loss;
  1317.             shkp->mgold += loss;
  1318.             pline("%s %sand takes %ld zorkmid%s %sowed %s.",
  1319.                   Monnam(shkp),
  1320.                   (shkp->msleep || !shkp->mcanmove) ?
  1321.                     "wakes up " : "comes ",
  1322.                   loss, plur(loss),
  1323.                   strncmp(eshkp->customer,
  1324.                        plname, PL_NSIZ) ? "" : "you ",
  1325.                   shkp->female ? "her" : "him");
  1326.         }
  1327. skip:
  1328.         /* in case we create bones */
  1329.         if(!inhishop(shkp))
  1330.             home_shk(shkp, FALSE);
  1331.     }
  1332. clear:
  1333.     setpaid(shkp);
  1334.     return(taken);
  1335. }
  1336.  
  1337. /* find obj on one of the lists */
  1338. static struct obj *
  1339. bp_to_obj(bp)
  1340. register struct bill_x *bp;
  1341. {
  1342.     register struct obj *obj;
  1343.     register struct monst *mtmp;
  1344.     register unsigned int id = bp->bo_id;
  1345.  
  1346.     if(bp->useup)
  1347.         obj = o_on(id, billobjs);
  1348.     else if(!(obj = o_on(id, invent)) &&
  1349.         !(obj = o_on(id, fobj)) &&
  1350.         !(obj = o_on(id, level.buriedobjlist)) &&
  1351.         !(obj = o_on(id, migrating_objs))) {
  1352.             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1353.             if ((obj = o_on(id, mtmp->minvent)) != 0)
  1354.                 return obj;
  1355.             for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
  1356.             if ((obj = o_on(id, mtmp->minvent)) != 0)
  1357.                 return obj;
  1358.         }
  1359.     return(obj);
  1360. }
  1361.  
  1362. /* calculate the value that the shk will charge for [one of] an object */
  1363. static long
  1364. get_cost(obj, shkp)
  1365. register struct obj *obj;
  1366. register struct monst *shkp;    /* if angry, impose a surcharge */
  1367. {
  1368.     register long tmp = getprice(obj);
  1369.  
  1370.     if (!tmp) tmp = 5L;
  1371.     /* shopkeeper may notice if the player isn't very knowledgeable -
  1372.        especially when gem prices are concerned */
  1373.     if (!objects[obj->otyp].oc_name_known)
  1374.         if (obj->oclass == GEM_CLASS) {
  1375.             /* all gems are priced high - real or not */
  1376.             if (objects[obj->otyp].oc_material == GLASS) {
  1377.                 /* real gem's cost (worthless gems come
  1378.                    after jade but before luckstone) */
  1379.                 tmp = (long)objects[
  1380.                     obj->otyp - LUCKSTONE + JADE + 1].oc_cost;
  1381.             }
  1382.         } else if (!(obj->o_id % 4)) /* arbitrarily impose surcharge */
  1383.             tmp += tmp / 3L;
  1384. #ifdef TOURIST
  1385.     if((pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1386.         || (uarmu && !uarm && !uarmc))    /* Hawaiian shirt visible */
  1387.         tmp += tmp / 3L;
  1388. #endif
  1389.     if (ACURR(A_CHA) > 18)        tmp /= 2L;
  1390.     else if (ACURR(A_CHA) > 17)    tmp -= tmp / 3L;
  1391.     else if (ACURR(A_CHA) > 15)    tmp -= tmp / 4L;
  1392.     else if (ACURR(A_CHA) < 6)    tmp *= 2L;
  1393.     else if (ACURR(A_CHA) < 8)    tmp += tmp / 2L;
  1394.     else if (ACURR(A_CHA) < 11)    tmp += tmp / 3L;
  1395.     if (tmp <= 0L) tmp = 1L;
  1396.     else if (obj->oartifact) tmp *= 4L;
  1397.     /* anger surcharge should match rile_shk's */
  1398.     if (shkp && ESHK(shkp)->surcharge) tmp += (tmp + 2L) / 3L;
  1399.     return tmp;
  1400. }
  1401.  
  1402. /* returns the price of a container's content.  the price
  1403.  * of the "top" container is added in the calling functions.
  1404.  * a different price quoted for selling as vs. buying.
  1405.  */
  1406. long
  1407. contained_cost(obj, shkp, price, usell)
  1408. register struct obj *obj;
  1409. register struct monst *shkp;
  1410. long price;
  1411. register boolean usell;
  1412. {
  1413.     register struct obj *otmp;
  1414.  
  1415.     /* the price of contained objects */
  1416.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1417.         register boolean goods = saleable(rooms[ESHK(shkp)->shoproom -
  1418.                        ROOMOFFSET].rtype-SHOPBASE, otmp);
  1419.  
  1420.         if(otmp->oclass == GOLD_CLASS) continue;
  1421.  
  1422.         /* the "top" container is evaluated by caller */
  1423.         if(usell) {
  1424.         if(goods && !otmp->unpaid &&
  1425.             otmp->oclass != BALL_CLASS &&
  1426.             !(otmp->oclass == FOOD_CLASS && otmp->oeaten) &&
  1427.             !(Is_candle(otmp) && otmp->age <
  1428.                 20L * (long)objects[otmp->otyp].oc_cost))
  1429.             price += set_cost(otmp, shkp);
  1430.         } else if(!otmp->no_charge) {
  1431.             price += get_cost(otmp, shkp);
  1432.         }
  1433.  
  1434.         if (Has_contents(otmp))
  1435.             price += contained_cost(otmp, shkp, price, usell);
  1436.     }
  1437.  
  1438.     return(price);
  1439. }
  1440.  
  1441. long
  1442. contained_gold(obj)
  1443. register struct obj *obj;
  1444. {
  1445.     register struct obj *otmp;
  1446.     register long value = 0L;
  1447.  
  1448.     /* accumulate contained gold */
  1449.     for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
  1450.         if (otmp->oclass == GOLD_CLASS)
  1451.         value += otmp->quan;
  1452.         else if (Has_contents(otmp))
  1453.         value += contained_gold(otmp);
  1454.  
  1455.     return(value);
  1456. }
  1457.  
  1458. static void
  1459. dropped_container(obj, shkp, sale)
  1460. register struct obj *obj;
  1461. register struct monst *shkp;
  1462. register boolean sale;
  1463. {
  1464.     register struct obj *otmp;
  1465.     register boolean saleitem;
  1466.  
  1467.     /* the "top" container is treated in the calling fn */
  1468.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1469.  
  1470.         if(otmp->oclass == GOLD_CLASS) continue;
  1471.  
  1472.         saleitem = saleable(rooms[ESHK(shkp)->shoproom -
  1473.                     ROOMOFFSET].rtype-SHOPBASE, otmp);
  1474.  
  1475.         if(!otmp->unpaid && !(sale && saleitem))
  1476.         otmp->no_charge = 1;
  1477.  
  1478.         if (Has_contents(otmp))
  1479.         dropped_container(otmp, shkp, sale);
  1480.     }
  1481. }
  1482.  
  1483. void
  1484. picked_container(obj)
  1485. register struct obj *obj;
  1486. {
  1487.     register struct obj *otmp;
  1488.  
  1489.     /* the "top" container is treated in the calling fn */
  1490.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1491.  
  1492.         if(otmp->oclass == GOLD_CLASS) continue;
  1493.  
  1494.         if(otmp->no_charge)
  1495.         otmp->no_charge = 0;
  1496.  
  1497.         if (Has_contents(otmp))
  1498.         picked_container(otmp);
  1499.     }
  1500. }
  1501.  
  1502. /* calculate how much the shk will pay when buying [all of] an object */
  1503. static long
  1504. set_cost(obj, shkp)
  1505. register struct obj *obj;
  1506. register struct monst *shkp;
  1507. {
  1508.     long tmp = getprice(obj) * obj->quan;
  1509.  
  1510. #ifdef TOURIST
  1511.     if ((pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1512.         || (uarmu && !uarm && !uarmc))    /* Hawaiian shirt visible */
  1513.         tmp /= 3L;
  1514.     else
  1515. #endif
  1516.         tmp /= 2L;
  1517.     /* shopkeeper may notice if the player isn't very knowledgeable -
  1518.        especially when gem prices are concerned */
  1519.     if (!objects[obj->otyp].oc_name_known) {
  1520.         if (obj->oclass == GEM_CLASS) {
  1521.             /* different shop keepers give different prices */
  1522.             if (objects[obj->otyp].oc_material == GEMSTONE ||
  1523.                 objects[obj->otyp].oc_material == GLASS) {
  1524.                 tmp = (obj->otyp % (6 - shkp->m_id % 3));
  1525.                 tmp = (tmp + 3) * obj->quan;
  1526.             }
  1527.         } else if (tmp > 1L && !rn2(4))
  1528.             tmp -= tmp / 4L;
  1529.     }
  1530.     return tmp;
  1531. }
  1532.  
  1533. /* called from doinv(invent.c) for inventory of unpaid objects */
  1534. long
  1535. unpaid_cost(unp_obj)
  1536. register struct obj *unp_obj;    /* known to be unpaid */
  1537. {
  1538.     register struct bill_x *bp = (struct bill_x *)0;
  1539.     register struct monst *shkp;
  1540.  
  1541.     for(shkp = next_shkp(fmon, TRUE); shkp;
  1542.                     shkp = next_shkp(shkp->nmon, TRUE))
  1543.         if ((bp = onbill(unp_obj, shkp, TRUE)) != 0) break;
  1544.  
  1545.     /* onbill() gave no message if unexpected problem occurred */
  1546.     if(!bp) impossible("unpaid_cost: object wasn't on any bill!");
  1547.  
  1548.     return bp ? unp_obj->quan * bp->price : 0L;
  1549. }
  1550.  
  1551. static void
  1552. add_one_tobill(obj, dummy)
  1553. register struct obj *obj;
  1554. register boolean dummy;
  1555. {
  1556.     register struct monst *shkp;
  1557.     register struct bill_x *bp;
  1558.     register int bct;
  1559.     register char roomno = *u.ushops;
  1560.  
  1561.     if(!*u.ushops) return;
  1562.  
  1563.     if(!(shkp = shop_keeper(roomno))) return;
  1564.  
  1565.     if(!inhishop(shkp)) return;
  1566.  
  1567.     if(onbill(obj, shkp, FALSE) || /* perhaps thrown away earlier */
  1568.             (obj->oclass == FOOD_CLASS && obj->oeaten))
  1569.         return;
  1570.  
  1571.     if(ESHK(shkp)->billct == BILLSZ) {
  1572.         You("got that for free!");
  1573.         return;
  1574.     }
  1575.  
  1576.     /* To recognize objects the shopkeeper is not interested in. -dgk
  1577.      */
  1578.     if (obj->no_charge) {
  1579.         obj->no_charge = 0;
  1580.         return;
  1581.     }
  1582.  
  1583.     bct = ESHK(shkp)->billct;
  1584.     bp = &(ESHK(shkp)->bill_p[bct]);
  1585.     bp->bo_id = obj->o_id;
  1586.     bp->bquan = obj->quan;
  1587.     if(dummy) {          /* a dummy object must be inserted into  */
  1588.         bp->useup = 1;      /* the billobjs chain here.  crucial for */
  1589.         obj->nobj = billobjs; /* eating floorfood in shop.  see eat.c  */
  1590.         billobjs = obj;
  1591.     } else    bp->useup = 0;
  1592.     bp->price = get_cost(obj, shkp);
  1593.     ESHK(shkp)->billct++;
  1594.     obj->unpaid = 1;
  1595. }
  1596.  
  1597. /* recursive billing of objects within containers. */
  1598. static void
  1599. bill_box_content(obj, ininv, dummy, shkp)
  1600. register struct obj *obj;
  1601. register boolean ininv, dummy;
  1602. register struct monst *shkp;
  1603. {
  1604.     register struct obj *otmp;
  1605.  
  1606.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1607.  
  1608.         if(otmp->oclass == GOLD_CLASS) continue;
  1609.         /* the "top" box is added in addtobill() */
  1610.         if(!otmp->no_charge)
  1611.             add_one_tobill(otmp, dummy);
  1612.         if (Has_contents(otmp))
  1613.             bill_box_content(otmp, ininv, dummy, shkp);
  1614.     }
  1615.  
  1616. }
  1617.  
  1618. static void
  1619. shk_names_obj(obj)
  1620. register struct obj *obj;
  1621. /* shopkeeper tells you what an object is */
  1622. {
  1623.     obj->dknown = TRUE;
  1624.     /* use real name for ordinary weapons/armor, and spell-less
  1625.      * scrolls/books (that is, blank and mail).
  1626.      */
  1627.     if (!objects[obj->otyp].oc_magic &&
  1628.         (obj->oclass == WEAPON_CLASS || obj->oclass == ARMOR_CLASS ||
  1629.          obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS))
  1630.         makeknown(obj->otyp);
  1631. }
  1632.  
  1633. void
  1634. addtobill(obj, ininv, dummy, silent)
  1635. register struct obj *obj;
  1636. register boolean ininv, dummy, silent;
  1637. {
  1638.     register struct monst *shkp;
  1639.     register char roomno = *u.ushops;
  1640.     long ltmp = 0L, cltmp = 0L, gltmp = 0L;
  1641.     register boolean container = Has_contents(obj);
  1642.  
  1643.     if(!*u.ushops) return;
  1644.  
  1645.     if(!(shkp = shop_keeper(roomno))) return;
  1646.  
  1647.     if(!inhishop(shkp)) return;
  1648.  
  1649.     if(/* perhaps we threw it away earlier */
  1650.          onbill(obj, shkp, FALSE) ||
  1651.          (obj->oclass == FOOD_CLASS && obj->oeaten)
  1652.           ) return;
  1653.  
  1654.     if(ESHK(shkp)->billct == BILLSZ) {
  1655.         You("got that for free!");
  1656.         return;
  1657.     }
  1658.  
  1659.     if(obj->oclass == GOLD_CLASS) {
  1660.         costly_gold(obj->ox, obj->oy, obj->quan);
  1661.         return;
  1662.     }
  1663.  
  1664.     if(!obj->no_charge)
  1665.         ltmp = get_cost(obj, shkp);
  1666.  
  1667.     if (obj->no_charge && !container) {
  1668.         obj->no_charge = 0;
  1669.         return;
  1670.     }
  1671.  
  1672.     if(container) {
  1673.         if(obj->cobj == (struct obj *)0) {
  1674.         if(obj->no_charge) {
  1675.             obj->no_charge = 0;
  1676.             return;
  1677.         } else {
  1678.             add_one_tobill(obj, dummy);
  1679.             goto speak;
  1680.         }
  1681.         } else {
  1682.         cltmp += contained_cost(obj, shkp, cltmp, FALSE);
  1683.         gltmp += contained_gold(obj);
  1684.         }
  1685.  
  1686.         if(ltmp) add_one_tobill(obj, dummy);
  1687.         if(cltmp) bill_box_content(obj, ininv, dummy, shkp);
  1688.         picked_container(obj); /* reset contained obj->no_charge */
  1689.  
  1690.         ltmp += cltmp;
  1691.  
  1692.         if(gltmp) {
  1693.         costly_gold(obj->ox, obj->oy, gltmp);
  1694.         if(!ltmp) return;
  1695.         }
  1696.  
  1697.         if(obj->no_charge)
  1698.         obj->no_charge = 0;
  1699.  
  1700.     } else /* i.e., !container */
  1701.         add_one_tobill(obj, dummy);
  1702. speak:
  1703.     if (shkp->mcanmove && !shkp->msleep && !silent) {
  1704.         char buf[BUFSZ];
  1705.  
  1706.         if(!ltmp) {
  1707.         pline("%s has no interest in %s.", Monnam(shkp),
  1708.                          the(xname(obj)));
  1709.         return;
  1710.         }
  1711.         Strcpy(buf, "\"For you, ");
  1712.         if (ANGRY(shkp)) Strcat(buf, "scum ");
  1713.         else {
  1714.         static const char *honored[5] = {
  1715.           "good", "honored", "most gracious", "esteemed",
  1716.           "most renowned and sacred"
  1717.         };
  1718.         Strcat(buf, honored[rn2(4) + u.uevent.udemigod]);
  1719. #ifdef POLYSELF
  1720.         if(!is_human(uasmon)) Strcat(buf, " creature");
  1721.         else
  1722. #endif
  1723.             Strcat(buf, (flags.female) ? " lady" : " sir");
  1724.         }
  1725.         if(ininv) {
  1726.         long quan = obj->quan;
  1727.         obj->quan = 1L; /* fool xname() into giving singular */
  1728.         pline("%s; only %ld %s %s.\"", buf, ltmp,
  1729.             (quan > 1L) ? "per" : "for this", xname(obj));
  1730.         obj->quan = quan;
  1731.         } else
  1732.         pline("%s will cost you %ld zorkmid%s%s.",
  1733.             The(xname(obj)), ltmp, plur(ltmp),
  1734.             (obj->quan > 1L) ? " each" : "");
  1735.     } else if(!silent) {
  1736.         if(ltmp) pline("The list price of %s is %ld zorkmid%s%s.",
  1737.                    the(xname(obj)), ltmp, plur(ltmp),
  1738.                    (obj->quan > 1L) ? " each" : "");
  1739.         else pline("%s does not notice.", Monnam(shkp));
  1740.     }
  1741. }
  1742.  
  1743. void
  1744. splitbill(obj, otmp)
  1745. register struct obj *obj, *otmp;
  1746. {
  1747.     /* otmp has been split off from obj */
  1748.     register struct bill_x *bp;
  1749.     register long tmp;
  1750.     register struct monst *shkp = shop_keeper(*u.ushops);
  1751.  
  1752.     if(!shkp || !inhishop(shkp)) {
  1753.         impossible("splitbill: no resident shopkeeper??");
  1754.         return;
  1755.     }
  1756.     bp = onbill(obj, shkp, FALSE);
  1757.     if(!bp) {
  1758.         impossible("splitbill: not on bill?");
  1759.         return;
  1760.     }
  1761.     if(bp->bquan < otmp->quan) {
  1762.         impossible("Negative quantity on bill??");
  1763.     }
  1764.     if(bp->bquan == otmp->quan) {
  1765.         impossible("Zero quantity on bill??");
  1766.     }
  1767.     bp->bquan -= otmp->quan;
  1768.  
  1769.     if(ESHK(shkp)->billct == BILLSZ) otmp->unpaid = 0;
  1770.     else {
  1771.         tmp = bp->price;
  1772.         bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
  1773.         bp->bo_id = otmp->o_id;
  1774.         bp->bquan = otmp->quan;
  1775.         bp->useup = 0;
  1776.         bp->price = tmp;
  1777.         ESHK(shkp)->billct++;
  1778.     }
  1779. }
  1780.  
  1781. static void
  1782. sub_one_frombill(obj, shkp)
  1783. register struct obj *obj;
  1784. register struct monst *shkp;
  1785. {
  1786.     register struct bill_x *bp;
  1787.  
  1788.     if((bp = onbill(obj, shkp, FALSE)) != 0) {
  1789.         register struct obj *otmp;
  1790.  
  1791.         obj->unpaid = 0;
  1792.         if(bp->bquan > obj->quan){
  1793.             otmp = newobj(0);
  1794.             *otmp = *obj;
  1795.             bp->bo_id = otmp->o_id = flags.ident++;
  1796.             otmp->quan = (bp->bquan -= obj->quan);
  1797.             otmp->owt = 0;    /* superfluous */
  1798.             otmp->onamelth = 0;
  1799.             bp->useup = 1;
  1800.             otmp->nobj = billobjs;
  1801.             billobjs = otmp;
  1802.             return;
  1803.         }
  1804.         ESHK(shkp)->billct--;
  1805. #ifdef DUMB
  1806.         {
  1807.         /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  1808.             int indx = ESHK(shkp)->billct;
  1809.             *bp = ESHK(shkp)->bill_p[indx];
  1810.         }
  1811. #else
  1812.         *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
  1813. #endif
  1814.         return;
  1815.     } else if (obj->unpaid) {
  1816.         impossible("sub_one_frombill: unpaid object not on bill");
  1817.         obj->unpaid = 0;
  1818.     }
  1819. }
  1820.  
  1821. /* recursive check of unpaid objects within nested containers. */
  1822. void
  1823. subfrombill(obj, shkp)
  1824. register struct obj *obj;
  1825. register struct monst *shkp;
  1826. {
  1827.     register struct obj *otmp;
  1828.  
  1829.     sub_one_frombill(obj, shkp);
  1830.  
  1831.     if (Has_contents(obj))
  1832.         for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1833.         if(otmp->oclass == GOLD_CLASS) continue;
  1834.  
  1835.         if (Has_contents(otmp))
  1836.             subfrombill(otmp, shkp);
  1837.         else
  1838.             sub_one_frombill(otmp, shkp);
  1839.         }
  1840. }
  1841.  
  1842. static long
  1843. stolen_container(obj, shkp, price, ininv)
  1844. register struct obj *obj;
  1845. register struct monst *shkp;
  1846. long price;
  1847. register boolean ininv;
  1848. {
  1849.     register struct obj *otmp;
  1850.  
  1851.     if(ininv && obj->unpaid)
  1852.         price += get_cost(obj, shkp);
  1853.     else {
  1854.         if(!obj->no_charge)
  1855.         price += get_cost(obj, shkp);
  1856.         obj->no_charge = 0;
  1857.     }
  1858.  
  1859.     /* the price of contained objects, if any */
  1860.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1861.  
  1862.         if(otmp->oclass == GOLD_CLASS) continue;
  1863.  
  1864.         if (!Has_contents(otmp)) {
  1865.         if(ininv) {
  1866.             if(otmp->unpaid)
  1867.             price += get_cost(otmp, shkp);
  1868.         } else {
  1869.             if(!otmp->no_charge) {
  1870.             if(!(otmp->oclass == BALL_CLASS ||
  1871.                 (otmp->oclass == FOOD_CLASS && otmp->oeaten) ||
  1872.                 (Is_candle(otmp) && otmp->age <
  1873.                   20L * (long)objects[otmp->otyp].oc_cost))
  1874.               ) price += get_cost(otmp, shkp);
  1875.             }
  1876.             otmp->no_charge = 0;
  1877.         }
  1878.         } else
  1879.         price += stolen_container(otmp, shkp, price, ininv);
  1880.     }
  1881.  
  1882.     return(price);
  1883. }
  1884.  
  1885. long
  1886. stolen_value(obj, x, y, peaceful, silent)
  1887. register struct obj *obj;
  1888. register xchar x, y;
  1889. register boolean peaceful, silent;
  1890. {
  1891.     register long value = 0L, gvalue = 0L;
  1892.     register struct monst *shkp;
  1893.     register boolean goods;
  1894.  
  1895.     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
  1896.  
  1897.     if (!shkp || !inhishop(shkp))
  1898.         return (0L);
  1899.  
  1900.     goods = saleable(rooms[ESHK(shkp)->shoproom -
  1901.                    ROOMOFFSET].rtype-SHOPBASE, obj);
  1902.     goods = (goods && !obj->no_charge);
  1903.  
  1904.     if(obj->oclass == GOLD_CLASS) {
  1905.         gvalue += obj->quan;
  1906.     } else if (Has_contents(obj)) {
  1907.         register boolean ininv = !!count_unpaid(obj->cobj);
  1908.  
  1909.         value += stolen_container(obj, shkp, value, ininv);
  1910.         if(!ininv) gvalue += contained_gold(obj);
  1911.     } else if(goods) {
  1912.         value += get_cost(obj, shkp);
  1913.     }
  1914.  
  1915.     if(gvalue + value == 0L) return(0L);
  1916.  
  1917.     value += gvalue;
  1918.  
  1919.     if(peaceful) {
  1920.         value = check_credit(value, shkp);
  1921.         ESHK(shkp)->debit += value;
  1922.  
  1923.         if(!silent) {
  1924.         if(obj->oclass == GOLD_CLASS)
  1925.             You("owe %s %ld zorkmids!", mon_nam(shkp), value);
  1926.         else You("owe %s %ld zorkmids for %s!",
  1927.             mon_nam(shkp),
  1928.             value,
  1929.             obj->quan > 1L ? "them" : "it");
  1930.         }
  1931.     } else {
  1932.         ESHK(shkp)->robbed += value;
  1933.  
  1934.         if(!silent) {
  1935.         if(cansee(shkp->mx, shkp->my)) {
  1936.             if(ESHK(shkp)->customer[0] == 0)
  1937.             (void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
  1938.             Norep("%s booms: \"%s, you are a thief!\"",
  1939.                 Monnam(shkp), plname);
  1940.         } else  Norep("You hear a scream, \"Thief!\"");
  1941.         }
  1942.         hot_pursuit(shkp);
  1943.         (void) angry_guards(FALSE);
  1944.     }
  1945.     return(value);
  1946. }
  1947.  
  1948. /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */
  1949. static char sell_response = 'a';
  1950.  
  1951. void
  1952. sellobj_state(deliberate)    /* called from dodrop(do.c) and doddrop() */
  1953. register boolean deliberate;
  1954. {
  1955.     /* If we're deliberately dropping something, there's no automatic
  1956.     response to the shopkeeper's "want to sell" query; however, if we
  1957.     accidentally drop anything, the shk will buy it/them without asking.
  1958.     This retains the old pre-query risk that slippery fingers while in
  1959.     shops entailed:  you drop it, you've lost it.
  1960.      */
  1961.     sell_response = deliberate ? '\0' : 'a';
  1962. }
  1963.  
  1964. void
  1965. sellobj(obj, x, y)
  1966. register struct obj *obj;
  1967. register xchar x, y;
  1968. {
  1969.     register struct monst *shkp;
  1970.     register struct eshk *eshkp;
  1971.     register long ltmp = 0L, cltmp = 0L, gltmp = 0L, offer;
  1972.     boolean saleitem, cgold = FALSE, container = Has_contents(obj);
  1973.     boolean isgold = (obj->oclass == GOLD_CLASS);
  1974.  
  1975.     if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) ||
  1976.        !inhishop(shkp)) return;
  1977.     if(!costly_spot(x, y))    return;
  1978.     if(!*u.ushops) return;
  1979.  
  1980.     saleitem = saleable(rooms[ESHK(shkp)->shoproom -
  1981.                     ROOMOFFSET].rtype-SHOPBASE, obj);
  1982.  
  1983.     if(obj->unpaid && !container && !isgold) {
  1984.         sub_one_frombill(obj, shkp);
  1985.         return;
  1986.     }
  1987.     if(container) {
  1988.         /* find the price of content before subfrombill */
  1989.         cltmp += contained_cost(obj, shkp, cltmp, TRUE);
  1990.         /* find the value of contained gold */
  1991.         gltmp += contained_gold(obj);
  1992.         cgold = (gltmp > 0L);
  1993.     }
  1994.  
  1995.     if(!isgold && !obj->unpaid && saleitem)
  1996.         ltmp = set_cost(obj, shkp);
  1997.  
  1998.     offer = ltmp + cltmp;
  1999.  
  2000.     /* get one case out of the way: nothing to sell, and no gold */
  2001.     if(!isgold && (offer + gltmp) == 0L) {
  2002.         register boolean unpaid = (obj->unpaid ||
  2003.                   (container && count_unpaid(obj->cobj)));
  2004.  
  2005.         if(container) {
  2006.             dropped_container(obj, shkp, FALSE);
  2007.             if(!obj->unpaid && !saleitem)
  2008.                 obj->no_charge = 1;
  2009.             if(obj->unpaid || count_unpaid(obj->cobj))
  2010.                 subfrombill(obj, shkp);
  2011.         } else obj->no_charge = 1;
  2012.  
  2013.         if(!unpaid)
  2014.             pline("%s seems uninterested.", Monnam(shkp));
  2015.         return;
  2016.     }
  2017.  
  2018.     /* you dropped something of your own - probably want to sell it */
  2019.     if (shkp->msleep || !shkp->mcanmove) {
  2020.         if (container)
  2021.             dropped_container(obj, shkp, TRUE);
  2022.         if (!obj->unpaid)
  2023.             obj->no_charge = 1;
  2024.         if (!shkp->mcanmove) {
  2025.             if(ANGRY(shkp) && !rn2(4))
  2026.             pline("%s utters a curse.", Monnam(shkp));
  2027.             else pline("%s is indisposed.", Monnam(shkp));
  2028.         } else if(!rn2(3)) {
  2029.             pline("%s snores indifferently.", Monnam(shkp));
  2030.         }
  2031.         subfrombill(obj, shkp);
  2032.         return;
  2033.     }
  2034.  
  2035.     eshkp = ESHK(shkp);
  2036.  
  2037.     if (ANGRY(shkp)) { /* they become shop-objects, no pay */
  2038.         pline("Thank you, scum!");
  2039.         subfrombill(obj, shkp);
  2040.         return;
  2041.     }
  2042.  
  2043.     if(eshkp->robbed) {  /* shkp is not angry? */
  2044.         if(isgold) offer = obj->quan;
  2045.         else if(cgold) offer += cgold;
  2046.         if((eshkp->robbed -= offer < 0L))
  2047.             eshkp->robbed = 0L;
  2048.         if(offer) verbalize(
  2049.   "Thank you for your contribution to restock this recently plundered shop.");
  2050.         subfrombill(obj, shkp);
  2051.         return;
  2052.     }
  2053.  
  2054.     if(isgold || cgold) {
  2055.         if(!cgold) gltmp = obj->quan;
  2056.  
  2057.         if(eshkp->debit >= gltmp) {
  2058.             if(eshkp->loan) { /* you carry shop's gold */
  2059.              if(eshkp->loan >= gltmp)
  2060.                  eshkp->loan -= gltmp;
  2061.              else eshkp->loan = 0L;
  2062.             }
  2063.             eshkp->debit -= gltmp;
  2064.             Your("debt is %spaid off.",
  2065.                 eshkp->debit ? "partially " : "");
  2066.         } else {
  2067.             long delta = gltmp - eshkp->debit;
  2068.  
  2069.             eshkp->credit += delta;
  2070.             if(eshkp->debit) {
  2071.             eshkp->debit = 0L;
  2072.             eshkp->loan = 0L;
  2073.             Your("debt is paid off.");
  2074.             }
  2075.             pline("%ld zorkmid%s added to your credit.",
  2076.                 delta, delta > 1L ? "s are" : " is");
  2077.         }
  2078.         if(offer) goto move_on;
  2079.         else {
  2080.             if(!isgold) {
  2081.             if (container)
  2082.                 dropped_container(obj, shkp, FALSE);
  2083.             if (!obj->unpaid && !saleitem) obj->no_charge = 1;
  2084.             subfrombill(obj, shkp);
  2085.             }
  2086.             return;
  2087.         }
  2088.     }
  2089. move_on:
  2090.     if((!saleitem && !(container && cltmp > 0L))
  2091.        || eshkp->billct == BILLSZ
  2092.        || obj->oclass == BALL_CLASS
  2093.        || obj->oclass == CHAIN_CLASS || offer == 0L
  2094.        || (obj->oclass == FOOD_CLASS && obj->oeaten)
  2095.        || (Is_candle(obj) &&
  2096.            obj->age < 20L * (long)objects[obj->otyp].oc_cost)) {
  2097.         pline("%s seems not interested%s.", Monnam(shkp),
  2098.             cgold ? " in the rest" : "");
  2099.         if (container)
  2100.             dropped_container(obj, shkp, FALSE);
  2101.         obj->no_charge = 1;
  2102.         return;
  2103.     }
  2104.  
  2105.     if(!shkp->mgold) {
  2106.         char c, qbuf[BUFSZ];
  2107.         long tmpcr = (ltmp + cltmp) * 2L;
  2108.  
  2109.         if (sell_response != 'n') {
  2110.             pline("%s cannot pay you at present.", Monnam(shkp));
  2111.             Sprintf(qbuf,
  2112.                 "Will you accept %ld zorkmids in credit for %s? ",
  2113.                 tmpcr, doname(obj));
  2114.             /* won't accept 'a' response here */
  2115.             c = ynq(qbuf);
  2116.         } else        /* previously specified "quit" */
  2117.             c = 'n';
  2118.  
  2119.         if (c == 'y') {
  2120.             You("have %ld zorkmids in %scredit.", tmpcr,
  2121.             ESHK(shkp)->credit > 0L ? "additional " : "");
  2122.             ESHK(shkp)->credit += tmpcr;
  2123.             subfrombill(obj, shkp);
  2124.         } else {
  2125.             if (c == 'q') sell_response = 'n';
  2126.             if (container)
  2127.             dropped_container(obj, shkp, FALSE);
  2128.             if (!obj->unpaid) obj->no_charge = 1;
  2129.             subfrombill(obj, shkp);
  2130.         }
  2131.     } else {
  2132.         int qlen;
  2133.         char qbuf[BUFSZ];
  2134.         boolean short_funds = (offer > shkp->mgold);
  2135.  
  2136.         if (short_funds) offer = shkp->mgold;
  2137.  
  2138.         if (!sell_response) {
  2139.             Sprintf(qbuf,
  2140.                 "%s offers%s %ld gold piece%s for%s your %s.",
  2141.                 Monnam(shkp), short_funds ? " only" : "",
  2142.                 offer, plur(offer),
  2143.                 (!ltmp && cltmp) ? " the contents of" : "",
  2144.                 xname(obj));
  2145.             qlen = strlen(qbuf);
  2146.             /*  Will the prompt fit on the topline? (or would
  2147.              *    "--more--" force line wrap anyway?)  If so, combine
  2148.              *    the message and prompt; otherwise, flush message
  2149.              *    and prompt separately.
  2150.              */
  2151.             if (qlen > COLNO - 24 && qlen <= COLNO - 8)
  2152.             pline(qbuf),  qbuf[0] = '\0';
  2153.             else  Strcat(qbuf, "  ");
  2154.             Strcat(strcat(qbuf, "Sell "),
  2155.                 (obj->quan == 1L ? "it?" : "them?"));
  2156.         } else  qbuf[0] = '\0';        /* just to pacify lint */
  2157.  
  2158.         switch (sell_response ? sell_response : ynaq(qbuf)) {
  2159.          case 'q':  sell_response = 'n';
  2160.          case 'n':  if (container)
  2161.                 dropped_container(obj, shkp, FALSE);
  2162.                 if (!obj->unpaid) obj->no_charge = 1;
  2163.                 subfrombill(obj, shkp);
  2164.                 break;
  2165.          case 'a':  sell_response = 'y';
  2166.          case 'y':  if (container)
  2167.                 dropped_container(obj, shkp, TRUE);
  2168.                 if (!obj->unpaid && !saleitem) obj->no_charge = 1;
  2169.                 subfrombill(obj, shkp);
  2170.                 pay(-offer, shkp);
  2171.                 shk_names_obj(obj);     /* identify some non-magic objects */
  2172.                 You("sold %s for %ld gold piece%s.", doname(obj),
  2173.                 offer, plur(offer));
  2174.                 break;
  2175.          default:   impossible("invalid sell response");
  2176.         }
  2177.     }
  2178. }
  2179.  
  2180. int
  2181. doinvbill(mode)
  2182. int mode;        /* 0: deliver count 1: paged */
  2183. {
  2184. #ifdef    __SASC
  2185.     void sasc_bug(struct obj *, unsigned);
  2186. #endif
  2187.     register struct monst* shkp;
  2188.     register struct bill_x *bp, *end_bp;
  2189.     register struct obj *obj;
  2190.     long totused;
  2191.     char *buf_p;
  2192.     winid datawin;
  2193.  
  2194.     shkp = shop_keeper(*u.ushops);
  2195.  
  2196.     if(mode == 0) {
  2197.         register int cnt = 0;
  2198.  
  2199.         if(shkp && inhishop(shkp))
  2200.         for (bp = ESHK(shkp)->bill_p,
  2201.             end_bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
  2202.             bp < end_bp; bp++)
  2203.             if(bp->useup ||
  2204.                ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
  2205.             cnt++;
  2206.         return(cnt);
  2207.     }
  2208.  
  2209.     if(!shkp || !inhishop(shkp)) {
  2210.         impossible("doinvbill: no shopkeeper?");
  2211.         return(0);
  2212.     }
  2213.  
  2214.     datawin = create_nhwindow(NHW_MENU);
  2215.     putstr(datawin, 0, "Unpaid articles already used up:");
  2216.     putstr(datawin, 0, "");
  2217.  
  2218.     totused = 0L;
  2219.     for (bp = ESHK(shkp)->bill_p,
  2220.         end_bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
  2221.         bp < end_bp; bp++) {
  2222.         obj = bp_to_obj(bp);
  2223.         if(!obj) {
  2224.         impossible("Bad shopkeeper administration.");
  2225.         goto quit;
  2226.         }
  2227.         if(bp->useup || bp->bquan > obj->quan) {
  2228.         register long oquan, uquan, thisused;
  2229.         unsigned save_unpaid;
  2230.  
  2231.         save_unpaid = obj->unpaid;
  2232.         oquan = obj->quan;
  2233.         uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
  2234.         thisused = bp->price * uquan;
  2235.         totused += thisused;
  2236.         obj->quan = uquan;        /* cheat doname */
  2237.         obj->unpaid = 0;        /* ditto */
  2238.         buf_p = xprname(obj, ' ', FALSE, thisused);
  2239.         obj->quan = oquan;        /* restore value */
  2240. #ifdef __SASC
  2241.                 /* SAS/C 6.2 can't cope for some reason */
  2242.         sasc_bug(obj,save_unpaid);
  2243. #else
  2244.         obj->unpaid = save_unpaid;
  2245. #endif
  2246.         putstr(datawin, 0, buf_p);
  2247.         }
  2248.     }
  2249.     buf_p = xprname((struct obj *)0, '*', FALSE, totused);
  2250.     putstr(datawin, 0, "");
  2251.     putstr(datawin, 0, buf_p);
  2252.     display_nhwindow(datawin, FALSE);
  2253.     quit:
  2254.     destroy_nhwindow(datawin);
  2255.     return(0);
  2256. }
  2257.  
  2258. #define HUNGRY    2
  2259.  
  2260. static long
  2261. getprice(obj)
  2262. register struct obj *obj;
  2263. {
  2264.     register long tmp = (long) objects[obj->otyp].oc_cost;
  2265.  
  2266.     switch(obj->oclass) {
  2267.     case FOOD_CLASS:
  2268.         /* simpler hunger check, (2-4)*cost */
  2269.         if (u.uhs >= HUNGRY) tmp *= (long) u.uhs;
  2270.         if (obj->oeaten) tmp = 0L;
  2271.         break;
  2272.     case WAND_CLASS:
  2273.         if (obj->spe == -1) tmp = 0L;
  2274.         break;
  2275.     case POTION_CLASS:
  2276.         if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
  2277.             tmp = 0L;
  2278.         break;
  2279.     case ARMOR_CLASS:
  2280.     case WEAPON_CLASS:
  2281.         if (obj->spe > 0) tmp += 10L * (long) obj->spe;
  2282.         break;
  2283.     case TOOL_CLASS:
  2284.         if (Is_candle(obj) &&
  2285.             obj->age < 20L * (long)objects[obj->otyp].oc_cost)
  2286.             tmp /= 2L;
  2287.         break;
  2288.     }
  2289.     if (obj->oartifact) tmp *= 25L;
  2290.     return tmp;
  2291. }
  2292.  
  2293. /* shk catches thrown pick-axe */
  2294. int
  2295. shkcatch(obj, x, y)
  2296. register struct obj *obj;
  2297. register xchar x, y;
  2298. {
  2299.     register struct monst *shkp;
  2300.  
  2301.     if (!(shkp = shop_keeper(inside_shop(x, y))) ||
  2302.         !inhishop(shkp)) return(0);
  2303.  
  2304.     if (shkp->mcanmove && !shkp->msleep &&
  2305.         (*u.ushops != ESHK(shkp)->shoproom || !inside_shop(u.ux, u.uy)) &&
  2306.         dist2(shkp->mx, shkp->my, x, y) < 3 &&
  2307.         /* if it is the shk's pos, you hit and anger him */
  2308.         (shkp->mx != x || shkp->my != y)) {
  2309.         if (mnearto(shkp, x, y, TRUE))
  2310.             verbalize("Out of my way, scum!");
  2311.         pline("%s nimbly catches %s.", Monnam(shkp), the(xname(obj)));
  2312.         mpickobj(shkp, obj);
  2313.         subfrombill(obj, shkp);
  2314.         return(1);
  2315.     }
  2316.     return(0);
  2317. }
  2318.  
  2319. void
  2320. add_damage(x, y, cost)
  2321. register xchar x, y;
  2322. long cost;
  2323. {
  2324.     struct damage *tmp_dam;
  2325.     char *shops;
  2326.  
  2327.     if (IS_DOOR(levl[x][y].typ))
  2328.         /* Don't schedule for repair unless it's a real shop entrance */
  2329.         for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++) {
  2330.         struct monst *mtmp = shop_keeper(*shops);
  2331.  
  2332.         if (!mtmp)
  2333.             continue;
  2334.         if ((x != ESHK(mtmp)->shd.x) || (y != ESHK(mtmp)->shd.y))
  2335.             return;
  2336.         }
  2337.     tmp_dam = (struct damage *)alloc((unsigned)sizeof(struct damage));
  2338.     tmp_dam->when = monstermoves;
  2339.     tmp_dam->place.x = x;
  2340.     tmp_dam->place.y = y;
  2341.     tmp_dam->cost = cost;
  2342.     tmp_dam->typ = levl[x][y].typ;
  2343.     tmp_dam->next = level.damagelist;
  2344.     level.damagelist = tmp_dam;
  2345.     /* If player saw damage, display as a wall forever */
  2346.     if (cansee(x, y))
  2347.         levl[x][y].seen = 1;
  2348. }
  2349.  
  2350. /*
  2351.  * Do something about damage. Either (!croaked) try to repair it, or
  2352.  * (croaked) just discard damage structs for non-shared locations, since
  2353.  * they'll never get repaired. Assume that shared locations will get
  2354.  * repaired eventually by the other shopkeeper(s). This might be an erroneous
  2355.  * assumption (they might all be dead too), but we have no reasonable way of
  2356.  * telling that.
  2357.  */
  2358. static
  2359. void
  2360. remove_damage(shkp, croaked)
  2361. register struct monst *shkp;
  2362. register boolean croaked;
  2363. {
  2364.     register struct damage *tmp_dam, *tmp2_dam;
  2365.     register boolean did_repair = FALSE, saw_door = FALSE;
  2366.     register boolean saw_floor = FALSE, stop_picking = FALSE;
  2367.     uchar saw_walls = 0;
  2368.  
  2369.     tmp_dam = level.damagelist;
  2370.     tmp2_dam = 0;
  2371.     while (tmp_dam) {
  2372.         register xchar x = tmp_dam->place.x, y = tmp_dam->place.y;
  2373.         char shops[5];
  2374.         uchar disposition;
  2375.  
  2376.         disposition = 0;
  2377.         Strcpy(shops, in_rooms(x, y, SHOPBASE));
  2378.         if (index(shops, ESHK(shkp)->shoproom)) {
  2379.         if (croaked)
  2380.             disposition = (shops[1])? 0 : 1;
  2381.         else if (stop_picking)
  2382.             disposition = repair_damage(shkp, tmp_dam);
  2383.         else {
  2384.             /* Defer the stop_occupation() until after repair msgs */
  2385.             if (closed_door(x, y))
  2386.             stop_picking = picking_at(x, y);
  2387.             disposition = repair_damage(shkp, tmp_dam);
  2388.             if (!disposition)
  2389.             stop_picking = FALSE;
  2390.         }
  2391.         }
  2392.  
  2393.         if (!disposition) {
  2394.         tmp2_dam = tmp_dam;
  2395.         tmp_dam = tmp_dam->next;
  2396.         continue;
  2397.         }
  2398.  
  2399.         if (disposition > 1) {
  2400.         did_repair = TRUE;
  2401.         if (cansee(x, y)) {
  2402.             if (IS_WALL(levl[x][y].typ))
  2403.             saw_walls++;
  2404.             else if (IS_DOOR(levl[x][y].typ))
  2405.             saw_door = TRUE;
  2406.             else
  2407.             saw_floor = TRUE;
  2408.         }
  2409.         }
  2410.  
  2411.         tmp_dam = tmp_dam->next;
  2412.         if (!tmp2_dam) {
  2413.         free((genericptr_t)level.damagelist);
  2414.         level.damagelist = tmp_dam;
  2415.         } else {
  2416.         free((genericptr_t)tmp2_dam->next);
  2417.         tmp2_dam->next = tmp_dam;
  2418.         }
  2419.     }
  2420.     if (!did_repair)
  2421.         return;
  2422.     if (saw_walls) {
  2423.         pline("Suddenly, %s section%s of wall close%s up!",
  2424.           (saw_walls == 1) ? "a" : (saw_walls <= 3) ?
  2425.                           "some" : "several",
  2426.           (saw_walls == 1) ? "" : "s", (saw_walls == 1) ? "s" : "");
  2427.         if (saw_door)
  2428.         pline("The shop door reappears!");
  2429.         if (saw_floor)
  2430.         pline("The floor is repaired!");
  2431.     } else {
  2432.         if (saw_door)
  2433.         pline("Suddenly, the shop door reappears!");
  2434.         else if (saw_floor)
  2435.         pline("Suddenly, the floor damage is gone!");
  2436.         else if (inside_shop(u.ux, u.uy) == ESHK(shkp)->shoproom)
  2437.         You("feel more claustrophobic than before.");
  2438.         else if (flags.soundok && !rn2(10))
  2439.         Norep("The dungeon acoustics noticeably change.");
  2440.     }
  2441.     if (stop_picking)
  2442.         stop_occupation();
  2443. }
  2444.  
  2445. /*
  2446.  * 0: repair postponed, 1: silent repair (no messages), 2: normal repair
  2447.  */
  2448. char
  2449. repair_damage(shkp, tmp_dam)
  2450. register struct monst *shkp;
  2451. register struct damage *tmp_dam;
  2452. {
  2453.     register xchar x, y, i;
  2454.     xchar litter[9];
  2455.     register struct monst *mtmp;
  2456.     register struct obj *otmp;
  2457.     register struct trap *ttmp;
  2458.  
  2459.     if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
  2460.         return(0);
  2461.     if (shkp->msleep || !shkp->mcanmove || ESHK(shkp)->following)
  2462.         return(0);
  2463.     x = tmp_dam->place.x;
  2464.     y = tmp_dam->place.y;
  2465.     if (!IS_ROOM(tmp_dam->typ)) {
  2466.         if ((x == u.ux) && (y == u.uy))
  2467. #ifdef POLYSELF
  2468.         if (!passes_walls(uasmon))
  2469. #endif
  2470.             return(0);
  2471.         if ((x == shkp->mx) && (y == shkp->my))
  2472.         return(0);
  2473.         if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
  2474.         return(0);
  2475.     }
  2476.     if ((ttmp = t_at(x, y)) != 0)
  2477.         deltrap(ttmp);
  2478.     if (IS_ROOM(tmp_dam->typ)) {
  2479.         /* No messages if player already filled trapdoor */
  2480.         if (!ttmp)
  2481.         return(1);
  2482.         newsym(x, y);
  2483.         return(2);
  2484.     }
  2485.     if (!ttmp && (tmp_dam->typ == levl[x][y].typ) &&
  2486.         (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
  2487.         /* No messages if player already replaced shop door */
  2488.         return(1);
  2489.     levl[x][y].typ = tmp_dam->typ;
  2490.     (void) memset((genericptr_t)litter, 0, sizeof(litter));
  2491.     if ((otmp = level.objects[x][y]) != 0) {
  2492.         /* Scatter objects haphazardly into the shop */
  2493. #define NEED_UPDATE 1
  2494. #define OPEN        2
  2495. #define INSHOP        4
  2496. #define horiz(i) ((i%3)-1)
  2497. #define vert(i)  ((i/3)-1)
  2498.         for (i = 0; i < 9; i++) {
  2499.         if ((i == 4) || (!ZAP_POS(levl[x+horiz(i)][y+vert(i)].typ)))
  2500.             continue;
  2501.         litter[i] = OPEN;
  2502.         if (inside_shop(x+horiz(i),
  2503.                 y+vert(i)) == ESHK(shkp)->shoproom)
  2504.             litter[i] |= INSHOP;
  2505.         }
  2506.         if (Punished && !u.uswallow &&
  2507.                 ((uchain->ox == x && uchain->oy == y) ||
  2508.                  (uball->ox == x && uball->oy == y))) {
  2509.         /*
  2510.          * Either the ball or chain is in the repair location.
  2511.          *
  2512.          * Take the easy way out and put ball&chain under hero.
  2513.          */
  2514.         verbalize("Get your junk out of my wall!");
  2515.         unplacebc();    /* pick 'em up */
  2516.         placebc();    /* put 'em down */
  2517.         }
  2518.         while ((otmp = level.objects[x][y]) != 0)
  2519.         /* Don't mess w/ boulders -- just merge into wall */
  2520.         if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) {
  2521.             freeobj(otmp);
  2522.             obfree(otmp, (struct obj *)0);
  2523.         } else {
  2524.             while (!(litter[i = rn2(9)] & INSHOP));
  2525.             remove_object(otmp);
  2526.             place_object(otmp, x+horiz(i), y+vert(i));
  2527.             litter[i] |= NEED_UPDATE;
  2528.         }
  2529.     }
  2530.     block_point(x, y);
  2531.     if(IS_DOOR(tmp_dam->typ)) {
  2532.         levl[x][y].doormask = D_CLOSED; /* arbitrary */
  2533.         newsym(x, y);
  2534.     } else {
  2535.         levl[x][y].doormask = D_NODOOR;
  2536.         if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
  2537.         /* Player sees actual repair process, so they KNOW it's a wall */
  2538.         levl[x][y].seen = 1;
  2539.         newsym(x, y);
  2540.         } else if (levl[x][y].seen) {
  2541.         /* Force a display update */
  2542.         levl[x][y].diggable |= W_REPAIRED;
  2543.         }
  2544.     }
  2545.     for (i = 0; i < 9; i++)
  2546.         if (litter[i] & NEED_UPDATE)
  2547.         newsym(x+horiz(i), y+vert(i));
  2548.     return(2);
  2549. #undef NEED_UPDATE
  2550. #undef OPEN
  2551. #undef INSHOP
  2552. #undef vert
  2553. #undef horiz
  2554. }
  2555.  
  2556. /*
  2557.  * shk_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
  2558.  */
  2559. int
  2560. shk_move(shkp)
  2561. register struct monst *shkp;
  2562. {
  2563.     register xchar gx,gy,omx,omy;
  2564.     register int udist;
  2565.     register schar appr;
  2566.     register struct eshk *eshkp = ESHK(shkp);
  2567.     int z;
  2568.     boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
  2569.  
  2570.     omx = shkp->mx;
  2571.     omy = shkp->my;
  2572.  
  2573.     if (inhishop(shkp))
  2574.         remove_damage(shkp, FALSE);
  2575.  
  2576.     if((udist = distu(omx,omy)) < 3 &&
  2577.        (shkp->data != &mons[PM_GRID_BUG] || (omx==u.ux || omy==u.uy))) {
  2578.         if(ANGRY(shkp) ||
  2579.            (Conflict && !resist(shkp, RING_CLASS, 0, 0))) {
  2580.             if(Displaced)
  2581.               Your("displaced image doesn't fool %s!",
  2582.                 mon_nam(shkp));
  2583.             (void) mattacku(shkp);
  2584.             return(0);
  2585.         }
  2586.         if(eshkp->following) {
  2587.             if(strncmp(eshkp->customer, plname, PL_NSIZ)) {
  2588.                 verbalize("Hello, %s!  I was looking for %s.",
  2589.                     plname, eshkp->customer);
  2590.                     eshkp->following = 0;
  2591.                 return(0);
  2592.             }
  2593.             if(moves > followmsg+4) {
  2594.                 verbalize("Hello, %s!  Didn't you forget to pay?",
  2595.                     plname);
  2596.                 followmsg = moves;
  2597.                 if (!rn2(4)) {
  2598.         pline ("%s doesn't like customers who don't pay.", Monnam(shkp));
  2599.                 rile_shk(shkp);
  2600.                 }
  2601.             }
  2602.             if(udist < 2)
  2603.                 return(0);
  2604.         }
  2605.     }
  2606.  
  2607.     appr = 1;
  2608.     gx = eshkp->shk.x;
  2609.     gy = eshkp->shk.y;
  2610.     satdoor = (gx == omx && gy == omy);
  2611.     if(eshkp->following || ((z = holetime()) >= 0 && z*z <= udist)){
  2612.         if(udist > 4)
  2613.             return(-1);    /* leave it to m_move */
  2614.         gx = u.ux;
  2615.         gy = u.uy;
  2616.     } else if(ANGRY(shkp)) {
  2617.         /* Move towards the hero if the shopkeeper can see him. */
  2618.         if(shkp->mcansee && m_canseeu(shkp)) {
  2619.             gx = u.ux;
  2620.             gy = u.uy;
  2621.         }
  2622.         avoid = FALSE;
  2623.     } else {
  2624. #define    GDIST(x,y)    (dist2(x,y,gx,gy))
  2625.         if(Invis) {
  2626.             avoid = FALSE;
  2627.         } else {
  2628.             uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
  2629.             if(uondoor) {
  2630.             badinv = (!!carrying(PICK_AXE));
  2631.             if(satdoor && badinv)
  2632.                 return(0);
  2633.             avoid = !badinv;
  2634.             } else {
  2635.             avoid = (*u.ushops && distu(gx,gy) > 8);
  2636.             badinv = FALSE;
  2637.             }
  2638.  
  2639.             if(((!eshkp->robbed && !eshkp->billct && !eshkp->debit)
  2640.             || avoid) && GDIST(omx,omy) < 3) {
  2641.             if (!badinv && !onlineu(omx,omy))
  2642.                 return(0);
  2643.             if(satdoor)
  2644.                 appr = gx = gy = 0;
  2645.             }
  2646.         }
  2647.     }
  2648.  
  2649.     return(move_special(shkp,inhishop(shkp),
  2650.                 appr,uondoor,avoid,omx,omy,gx,gy));
  2651. }
  2652.  
  2653. /* for use in levl_follower (mondata.c) */
  2654. boolean
  2655. is_fshk(mtmp)
  2656. register struct monst *mtmp;
  2657. {
  2658.     return((boolean)(mtmp->isshk && ESHK(mtmp)->following));
  2659. }
  2660.  
  2661. /* You are digging in the shop. */
  2662. void
  2663. shopdig(fall)
  2664. register int fall;
  2665. {
  2666.     register struct monst *shkp = shop_keeper(*u.ushops);
  2667.  
  2668.     if(!shkp) return;
  2669.  
  2670.     if(!inhishop(shkp)) {
  2671.     if (pl_character[0] == 'K') adjalign(-sgn(u.ualign.type));
  2672.     return;
  2673.     }
  2674.  
  2675.     if(!fall) {
  2676.     if(u.utraptype == TT_PIT)
  2677.         verbalize("Be careful, %s, or you might fall through the floor.",
  2678.         flags.female ? "madam" : "sir");
  2679.     else
  2680.         verbalize("%s, do not damage the floor here!",
  2681.             flags.female ? "Madam" : "Sir");
  2682.     if (pl_character[0] == 'K') adjalign(-sgn(u.ualign.type));
  2683.     } else if(!um_dist(shkp->mx, shkp->my, 5) &&
  2684.         !shkp->msleep && shkp->mcanmove &&
  2685.         (ESHK(shkp)->billct || ESHK(shkp)->debit)) {
  2686.         register struct obj *obj, *obj2;
  2687.  
  2688.         if (distu(shkp->mx, shkp->my) > 2) {
  2689.         mnexto(shkp);
  2690.         /* for some reason the shopkeeper can't come next to you */
  2691.         if (distu(shkp->mx, shkp->my) > 2) {
  2692.             pline("%s curses you in anger and frustration!",
  2693.                     shkname(shkp));
  2694.             rile_shk(shkp);
  2695.             return;
  2696.         } else pline("%s leaps, and grabs your backpack!",
  2697.                     shkname(shkp));
  2698.         } else pline("%s grabs your backpack!", shkname(shkp));
  2699.  
  2700.         for(obj = invent; obj; obj = obj2) {
  2701.         obj2 = obj->nobj;
  2702.         if(obj->owornmask) continue;
  2703. #ifdef WALKIES
  2704.         if(obj->otyp == LEASH && obj->leashmon) continue;
  2705. #endif
  2706.         freeinv(obj);
  2707.         obj->nobj = shkp->minvent;
  2708.         shkp->minvent = obj;
  2709.         subfrombill(obj, shkp);
  2710.         }
  2711.     }
  2712. }
  2713.  
  2714. #ifdef KOPS
  2715. STATIC_OVL void
  2716. makekops(mm)        /* returns the number of (all types of) Kops  made */
  2717. coord *mm;
  2718. {
  2719.     register int cnt = abs(depth(&u.uz)) + rnd(5);
  2720.     register int scnt = (cnt / 3) + 1;    /* at least one sarge */
  2721.     register int lcnt = (cnt / 6);        /* maybe a lieutenant */
  2722.     register int kcnt = (cnt / 9);        /* and maybe a kaptain */
  2723.  
  2724.     if (!(mons[PM_KEYSTONE_KOP].geno & G_EXTINCT)) {
  2725.         while(cnt--) {
  2726.         if (enexto(mm, mm->x, mm->y, &mons[PM_KEYSTONE_KOP]))
  2727.             (void) makemon(&mons[PM_KEYSTONE_KOP], mm->x, mm->y);
  2728.         }
  2729.     }
  2730.     if (!(mons[PM_KOP_SERGEANT].geno & G_EXTINCT)) {
  2731.         while(scnt--) {
  2732.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_SERGEANT]))
  2733.             (void) makemon(&mons[PM_KOP_SERGEANT], mm->x, mm->y);
  2734.         }
  2735.     }
  2736.     if (!(mons[PM_KOP_LIEUTENANT].geno & G_EXTINCT)) {
  2737.         while(lcnt--) {
  2738.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_LIEUTENANT]))
  2739.             (void) makemon(&mons[PM_KOP_LIEUTENANT], mm->x, mm->y);
  2740.         }
  2741.     }
  2742.     if (!(mons[PM_KOP_KAPTAIN].geno & G_EXTINCT)) {
  2743.         while(kcnt--) {
  2744.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_KAPTAIN]))
  2745.             (void) makemon(&mons[PM_KOP_KAPTAIN], mm->x, mm->y);
  2746.         }
  2747.     }
  2748. }
  2749. #endif    /* KOPS */
  2750.  
  2751. void
  2752. pay_for_damage(dmgstr)
  2753. const char *dmgstr;
  2754. {
  2755.     register struct monst *shkp = (struct monst *)0;
  2756.     char shops_affected[5];
  2757.     register boolean uinshp = (*u.ushops != '\0');
  2758.     char qbuf[80];
  2759.     register xchar x, y;
  2760.     register boolean dugwall = !strcmp(dmgstr, "dig into");
  2761.     struct damage *tmp_dam, *appear_here = 0;
  2762.     /* any number >= (80*80)+(24*24) would do, actually */
  2763.     long cost_of_damage = 0L;
  2764.     unsigned int nearest_shk = 7000, nearest_damage = 7000;
  2765.     int picks = 0;
  2766.  
  2767.     for (tmp_dam = level.damagelist;
  2768.          (tmp_dam && (tmp_dam->when == monstermoves));
  2769.          tmp_dam = tmp_dam->next) {
  2770.         char *shp;
  2771.  
  2772.         if (!tmp_dam->cost)
  2773.         continue;
  2774.         cost_of_damage += tmp_dam->cost;
  2775.         Strcpy(shops_affected,
  2776.            in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
  2777.         for (shp = shops_affected; *shp; shp++) {
  2778.         struct monst *tmp_shk;
  2779.         unsigned int shk_distance;
  2780.  
  2781.         if (!(tmp_shk = shop_keeper(*shp)))
  2782.             continue;
  2783.         if (tmp_shk == shkp) {
  2784.             unsigned int damage_distance =
  2785.                    distu(tmp_dam->place.x, tmp_dam->place.y);
  2786.  
  2787.             if (damage_distance < nearest_damage) {
  2788.             nearest_damage = damage_distance;
  2789.             appear_here = tmp_dam;
  2790.             }
  2791.             continue;
  2792.         }
  2793.         if (!inhishop(tmp_shk))
  2794.             continue;
  2795.         shk_distance = distu(tmp_shk->mx, tmp_shk->my);
  2796.         if (shk_distance > nearest_shk)
  2797.             continue;
  2798.         if ((shk_distance == nearest_shk) && picks) {
  2799.             if (rn2(++picks))
  2800.             continue;
  2801.         } else
  2802.             picks = 1;
  2803.         shkp = tmp_shk;
  2804.         nearest_shk = shk_distance;
  2805.         appear_here = tmp_dam;
  2806.         nearest_damage = distu(tmp_dam->place.x, tmp_dam->place.y);
  2807.         }
  2808.     }
  2809.  
  2810.     if (!cost_of_damage || !shkp)
  2811.         return;
  2812.  
  2813.     x = appear_here->place.x;
  2814.     y = appear_here->place.y;
  2815.  
  2816.     /* not the best introduction to the shk... */
  2817.     (void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
  2818.  
  2819.     /* if the shk is already on the war path, be sure it's all out */
  2820.     if(ANGRY(shkp) || ESHK(shkp)->following) {
  2821.         hot_pursuit(shkp);
  2822.         return;
  2823.     }
  2824.  
  2825.     /* if the shk is not in their shop.. */
  2826.     if(!*in_rooms(shkp->mx,shkp->my,SHOPBASE)) {
  2827.         if(!cansee(shkp->mx, shkp->my))
  2828.             return;
  2829.         goto getcad;
  2830.     }
  2831.  
  2832.     if(uinshp) {
  2833.         if(um_dist(shkp->mx, shkp->my, 1) &&
  2834.             !um_dist(shkp->mx, shkp->my, 3)) {
  2835.             pline("%s leaps towards you!", shkname(shkp));
  2836.             mnexto(shkp);
  2837.         }
  2838.         if(um_dist(shkp->mx, shkp->my, 1)) goto getcad;
  2839.     } else {
  2840.         /*
  2841.          * Make shkp show up at the door.  Effect:  If there is a monster
  2842.          * in the doorway, have the hero hear the shopkeeper yell a bit,
  2843.          * pause, then have the shopkeeper appear at the door, having
  2844.          * yanked the hapless critter out of the way.
  2845.          */
  2846.         if (MON_AT(x, y)) {
  2847.         if(flags.soundok) {
  2848.             You("hear an angry voice:");
  2849.             verbalize("Out of my way, scum!");
  2850.             wait_synch();
  2851. #if defined(UNIX) || defined(VMS)
  2852. # if defined(SYSV) || defined(ULTRIX) || defined(VMS)
  2853.             (void)
  2854. # endif
  2855.             sleep(1);
  2856. #endif
  2857.         }
  2858.         }
  2859.         (void) mnearto(shkp, x, y, TRUE);
  2860.     }
  2861.  
  2862.     if((um_dist(x, y, 1) && !uinshp) ||
  2863.             (u.ugold + ESHK(shkp)->credit) < cost_of_damage
  2864.                 || !rn2(50)) {
  2865.         if(um_dist(x, y, 1) && !uinshp) {
  2866.             pline("%s shouts:", shkname(shkp));
  2867.             verbalize("Who dared %s my %s?", dmgstr,
  2868.                      dugwall ? "shop" : "door");
  2869.         } else {
  2870. getcad:
  2871.             verbalize("How dare you %s my %s?", dmgstr,
  2872.                      dugwall ? "shop" : "door");
  2873.         }
  2874.         hot_pursuit(shkp);
  2875.         return;
  2876.     }
  2877.  
  2878.     if(Invis) Your("invisibility does not fool %s!", shkname(shkp));
  2879.     Sprintf(qbuf,"\"Cad!  You did %ld zorkmids worth of damage!\"  Pay? ",
  2880.          cost_of_damage);
  2881.     if(yn(qbuf) != 'n') {
  2882.         cost_of_damage = check_credit(cost_of_damage, shkp);
  2883.         u.ugold -= cost_of_damage;
  2884.         shkp->mgold += cost_of_damage;
  2885.         flags.botl = 1;
  2886.         pline("Mollified, %s accepts your restitution.",
  2887.             shkname(shkp));
  2888.         /* move shk back to his home loc */
  2889.         home_shk(shkp, FALSE);
  2890.         pacify_shk(shkp);
  2891.     } else {
  2892.         verbalize("Oh, yes!  You'll pay!");
  2893.         hot_pursuit(shkp);
  2894.         adjalign(-sgn(u.ualign.type));
  2895.     }
  2896. }
  2897.  
  2898. /* called in dokick.c when we kick an object that might be in a store */
  2899. boolean
  2900. costly_spot(x, y)
  2901. register xchar x, y;
  2902. {
  2903.     register struct monst *shkp;
  2904.  
  2905.     if (!level.flags.has_shop) return FALSE;
  2906.     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
  2907.     if(!shkp || !inhishop(shkp)) return(FALSE);
  2908.  
  2909.     return((boolean)(inside_shop(x, y) &&
  2910.         !(x == ESHK(shkp)->shk.x &&
  2911.             y == ESHK(shkp)->shk.y)));
  2912. }
  2913.  
  2914. /* called by dotalk(sounds.c) when #chatting; returns obj if location
  2915.    contains shop goods and shopkeeper is willing & able to speak */
  2916. struct obj *
  2917. shop_object(x, y)
  2918. register xchar x, y;
  2919. {
  2920.     register struct obj *otmp;
  2921.     register struct monst *shkp;
  2922.  
  2923.     if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
  2924.     return(struct obj *)0;
  2925.  
  2926.     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  2927.     if (otmp->otyp != GOLD_PIECE)
  2928.         break;
  2929.     /* note: otmp might have ->no_charge set, but that's ok */
  2930.     return (otmp && costly_spot(x, y) && NOTANGRY(shkp)
  2931.         && shkp->mcanmove && !shkp->msleep)
  2932.         ? otmp : (struct obj *)0;
  2933. }
  2934.  
  2935. /* give price quotes for all objects linked to this one (ie, on this spot) */
  2936. void
  2937. price_quote(first_obj)
  2938. register struct obj *first_obj;
  2939. {
  2940.     register struct obj *otmp;
  2941.     char buf[BUFSZ], price[40];
  2942.     long cost;
  2943.     int cnt = 0;
  2944.     winid tmpwin;
  2945.  
  2946.     tmpwin = create_nhwindow(NHW_MENU);
  2947.     putstr(tmpwin, 0, "Fine goods for sale:");
  2948.     putstr(tmpwin, 0, "");
  2949.     for (otmp = first_obj; otmp; otmp = otmp->nexthere) {
  2950.     if (otmp->otyp == GOLD_PIECE) {
  2951.      /* if (otmp == first_obj)  first_obj = otmp->nexthere; */
  2952.         continue;    /* don't quote a price on this */
  2953.     } else if (otmp->no_charge || otmp == uball || otmp == uchain) {
  2954.         Strcpy(price, "no charge");
  2955.     } else {
  2956.         cost = get_cost(otmp, (struct monst *)0);
  2957.         Sprintf(price, "%ld zorkmid%s%s", cost, plur(cost),
  2958.             otmp->quan > 1L ? " each" : "");
  2959.     }
  2960.     Sprintf(buf, "%s, %s", doname(otmp), price);
  2961.     putstr(tmpwin, 0, buf),  cnt++;
  2962.     }
  2963.     if (cnt > 1) {
  2964.     display_nhwindow(tmpwin, TRUE);
  2965.     } else if (cnt == 1) {
  2966.     if (first_obj->no_charge || first_obj == uball || first_obj == uchain){
  2967.         pline("%s!", buf);    /* buf still contains the string */
  2968.     } else {
  2969.         /* print cost in slightly different format, so can't reuse buf */
  2970.         cost = get_cost(first_obj, (struct monst *)0);
  2971.         pline("%s, price %ld zorkmid%s%s%s", doname(first_obj),
  2972.         cost, plur(cost), first_obj->quan > 1L ? " each" : "",
  2973.         shk_embellish(first_obj, cost));
  2974.     }
  2975.     }
  2976.     destroy_nhwindow(tmpwin);
  2977. }
  2978.  
  2979. static const char *
  2980. shk_embellish(itm, cost)
  2981. register struct obj *itm;
  2982. long cost;
  2983. {
  2984.     if (!rn2(3)) {
  2985.     register int o, choice = rn2(5);
  2986.     if (choice == 0) choice = (cost < 100L ? 1 : cost < 500L ? 2 : 3);
  2987.     switch (choice) {
  2988.         case 4:
  2989.         if (cost < 10L) break; else o = itm->oclass;
  2990.         if (o == FOOD_CLASS) return ", gourmets' delight!";
  2991.         if (objects[itm->otyp].oc_name_known
  2992.             ? objects[itm->otyp].oc_magic
  2993.             : (o == AMULET_CLASS || o == RING_CLASS   ||
  2994.                o == WAND_CLASS   || o == POTION_CLASS ||
  2995.                o == SCROLL_CLASS || o == SPBOOK_CLASS))
  2996.             return ", painstakingly developed!";
  2997.         return ", superb craftsmanship!";
  2998.         case 3: return ", finest quality.";
  2999.         case 2: return ", an excellent choice.";
  3000.         case 1: return ", a real bargain.";
  3001.        default: break;
  3002.     }
  3003.     } else if (itm->oartifact) {
  3004.     return ", one of a kind!";
  3005.     }
  3006.     return ".";
  3007. }
  3008.  
  3009. #ifdef SOUNDS
  3010. void
  3011. shk_chat(shkp)
  3012. register struct monst *shkp;
  3013. {
  3014.     register struct eshk *eshk = ESHK(shkp);
  3015.  
  3016.     if (ANGRY(shkp))
  3017.         pline("%s mentions how much %s dislikes %s customers.",
  3018.             shkname(shkp), he[shkp->female],
  3019.             eshk->robbed ? "non-paying" : "rude");
  3020.     else if (eshk->following)
  3021.         if (strncmp(eshk->customer, plname, PL_NSIZ)) {
  3022.             verbalize("Hello %s!  I was looking for %s.",
  3023.                 plname, eshk->customer);
  3024.             eshk->following = 0;
  3025.         } else {
  3026.             verbalize("Hello %s!  Didn't you forget to pay?", plname);
  3027.         }
  3028.     else if (eshk->billct) {
  3029.         register long total = addupbill(shkp) + eshk->debit;
  3030.         pline("%s says that your bill comes to %ld zorkmid%s.",
  3031.               shkname(shkp), total, plur(total));
  3032.     } else if (eshk->debit)
  3033.         pline("%s reminds you that you owe %s %ld zorkmid%s.",
  3034.               shkname(shkp), him[shkp->female],
  3035.               eshk->debit, plur(eshk->debit));
  3036.     else if (eshk->credit)
  3037.         pline("%s encourages you to use your %ld zorkmid%s of credit.",
  3038.               shkname(shkp), eshk->credit, plur(eshk->credit));
  3039.     else if (eshk->robbed)
  3040.         pline("%s complains about a recent robbery.", shkname(shkp));
  3041.     else if (shkp->mgold < 50)
  3042.         pline("%s complains that business is bad.", shkname(shkp));
  3043.     else if (shkp->mgold > 4000)
  3044.         pline("%s says that business is good.", shkname(shkp));
  3045.     else
  3046.         pline("%s talks about the problem of shoplifters.", shkname(shkp));
  3047. }
  3048. #endif  /* SOUNDS */
  3049.  
  3050. #ifdef KOPS
  3051. static void
  3052. kops_gone(silent)
  3053. register boolean silent;
  3054. {
  3055.     register int cnt = 0;
  3056.     register struct monst *mtmp, *mtmp2;
  3057.  
  3058.     /* turn off automatic resurrection of kops */
  3059.     allow_kops = FALSE;
  3060.  
  3061.     for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  3062.         mtmp2 = mtmp->nmon;
  3063.         if(mtmp->data->mlet == S_KOP) {
  3064.             mongone(mtmp);
  3065.             cnt++;
  3066.         }
  3067.     }
  3068.     if(cnt && !silent)
  3069.         pline("The Kops (disappointed) disappear into thin air.");
  3070.     allow_kops = TRUE;
  3071. }
  3072. #endif    /* KOPS */
  3073.  
  3074. static long
  3075. cost_per_charge(otmp)
  3076. register struct obj *otmp;
  3077. {
  3078.     register long tmp = 0L;
  3079.     register struct monst *shkp = shop_keeper(*u.ushops);
  3080.  
  3081.     if(!shkp || !inhishop(shkp)) return(0L); /* insurance */
  3082.     tmp = get_cost(otmp, shkp);
  3083.  
  3084.     /* The idea is to make the exhaustive use of */
  3085.     /* an unpaid item more expensive than buying */
  3086.     /* it outright.                     */
  3087.     if(otmp->otyp == MAGIC_LAMP) {             /* 1 */
  3088.         tmp += tmp / 3L;
  3089.     } else if(otmp->otyp == MAGIC_MARKER) {         /* 70 - 100 */
  3090.         /* no way to determine in advance   */
  3091.         /* how many charges will be wasted. */
  3092.         /* so, arbitrarily, one half of the */
  3093.         /* price per use.            */
  3094.         tmp /= 2L;
  3095.     } else if(otmp->otyp == BAG_OF_TRICKS ||     /* 1 - 20 */
  3096.           otmp->otyp == HORN_OF_PLENTY) {
  3097.         tmp /= 5L;
  3098.     } else if(otmp->otyp == CRYSTAL_BALL ||         /* 1 - 5 */
  3099.           otmp->otyp == OIL_LAMP ||         /* 1 - 10 */
  3100.           otmp->otyp == BRASS_LANTERN ||
  3101.          (otmp->otyp >= MAGIC_FLUTE &&
  3102.           otmp->otyp <= DRUM_OF_EARTHQUAKE) ||     /* 5 - 9 */
  3103.           otmp->oclass == WAND_CLASS) {         /* 3 - 11 */
  3104.             if (otmp->spe > 1) tmp /= 4L;
  3105.     } else if (otmp->oclass == SPBOOK_CLASS) {
  3106.             tmp -= tmp / 5L;
  3107.     } else if (otmp->otyp == CAN_OF_GREASE)
  3108.             tmp /= 10L;
  3109.     return(tmp);
  3110. }
  3111.  
  3112. /* for using charges of unpaid objects */
  3113. void
  3114. check_unpaid(otmp)
  3115. register struct obj *otmp;
  3116. {
  3117.     if(!*u.ushops) return;
  3118.  
  3119.     if(otmp->oclass != SPBOOK_CLASS && otmp->spe <= 0) return;
  3120.  
  3121.     if(otmp->unpaid) {
  3122.         register long tmp = cost_per_charge(otmp);
  3123.         register struct monst *shkp = shop_keeper(*u.ushops);
  3124.  
  3125.         if(!shkp || !inhishop(shkp)) return;
  3126.  
  3127.         if(otmp->oclass == SPBOOK_CLASS && tmp > 0L)
  3128.             pline("\"%sYou owe%s %ld zorkmids.\"",
  3129.             rn2(2) ? "This is no free library, cad!  " : "",
  3130.             ESHK(shkp)->debit > 0L ? " additional" : "", tmp);
  3131.         ESHK(shkp)->debit += tmp;
  3132.         exercise(A_WIS, TRUE);        /* you just got info */
  3133.     }
  3134. }
  3135.  
  3136. void
  3137. costly_gold(x, y, amount)
  3138. register xchar x, y;
  3139. register long amount;
  3140. {
  3141.     register long delta;
  3142.     register struct monst *shkp;
  3143.     register struct eshk *eshkp;
  3144.  
  3145.     if(!costly_spot(x, y)) return;
  3146.     /* shkp now guaranteed to exist by costly_spot() */
  3147.     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
  3148.  
  3149.     eshkp = ESHK(shkp);
  3150.     if(eshkp->credit >= amount) {
  3151.         if(eshkp->credit > amount)
  3152.         Your("credit is reduced by %ld zorkmid%s.",
  3153.                     amount, plur(amount));
  3154.         else Your("credit is erased.");
  3155.         eshkp->credit -= amount;
  3156.     } else {
  3157.         delta = amount - eshkp->credit;
  3158.         if(eshkp->credit)
  3159.         Your("credit is erased.");
  3160.         if(eshkp->debit)
  3161.         Your("debt increases by %ld zorkmid%s.",
  3162.                     delta, plur(delta));
  3163.         else You("owe %s %ld zorkmid%s.",
  3164.                 shkname(shkp), delta, plur(delta));
  3165.         eshkp->debit += delta;
  3166.         eshkp->loan += delta;
  3167.         eshkp->credit = 0L;
  3168.     }
  3169. }
  3170.  
  3171. /* used in domove to block diagonal shop-exit */
  3172. /* x,y should always be a door */
  3173. boolean
  3174. block_door(x,y)
  3175. register xchar x, y;
  3176. {
  3177.     register int roomno = *in_rooms(x, y, SHOPBASE);
  3178.     register struct monst *shkp;
  3179.  
  3180.     if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
  3181.     if(!IS_DOOR(levl[x][y].typ)) return(FALSE);
  3182.     if(roomno != *u.ushops) return(FALSE);
  3183.  
  3184.     if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
  3185.         return(FALSE);
  3186.  
  3187.     if(shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y
  3188.         /* Actually, the shk should be made to block _any_
  3189.          * door, including a door the player digs, if the
  3190.          * shk is within a 'jumping' distance.
  3191.          */
  3192.         && ESHK(shkp)->shd.x == x && ESHK(shkp)->shd.y == y
  3193.         && shkp->mcanmove && !shkp->msleep
  3194.         && (ESHK(shkp)->debit || ESHK(shkp)->billct ||
  3195.         ESHK(shkp)->robbed)) {
  3196.         pline("%s%s blocks your way!", shkname(shkp),
  3197.                 Invis ? " senses your motion and" : "");
  3198.         return(TRUE);
  3199.     }
  3200.     return(FALSE);
  3201. }
  3202.  
  3203. /* used in domove to block diagonal shop-entry */
  3204. /* u.ux, u.uy should always be a door */
  3205. boolean
  3206. block_entry(x,y)
  3207. register xchar x, y;
  3208. {
  3209.     register xchar sx, sy;
  3210.     register int roomno;
  3211.     register struct monst *shkp;
  3212.  
  3213.     if(!(IS_DOOR(levl[u.ux][u.uy].typ) &&
  3214.         levl[u.ux][u.uy].doormask == D_BROKEN)) return(FALSE);
  3215.  
  3216.     roomno = *in_rooms(x, y, SHOPBASE);
  3217.     if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
  3218.     if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
  3219.         return(FALSE);
  3220.  
  3221.     if(ESHK(shkp)->shd.x != u.ux || ESHK(shkp)->shd.y != u.uy)
  3222.         return(FALSE);
  3223.  
  3224.     sx = ESHK(shkp)->shk.x;
  3225.     sy = ESHK(shkp)->shk.y;
  3226.  
  3227.     if(shkp->mx == sx && shkp->my == sy
  3228.         && shkp->mcanmove && !shkp->msleep
  3229.         && (x == sx-1 || x == sx+1 || y == sy-1 || y == sy+1)
  3230.         && (Invis || carrying(PICK_AXE))
  3231.       ) {
  3232.         pline("%s%s blocks your way!", shkname(shkp),
  3233.                 Invis ? " senses your motion and" : "");
  3234.         return(TRUE);
  3235.     }
  3236.     return(FALSE);
  3237. }
  3238.  
  3239. #endif /* OVLB */
  3240.  
  3241. #ifdef __SASC
  3242. void
  3243. sasc_bug(struct obj *op, unsigned x){
  3244.     op->unpaid=x;
  3245. }
  3246. #endif
  3247.  
  3248. /*shk.c*/
  3249.